1 / 17

The ‘net_device’ structure

Discover the main kernel object responsible for managing a Linux system's network interface controller. Learn how experienced software developers utilize the locality of reference strategy to simplify code design and maintenance.

fknowles
Download Presentation

The ‘net_device’ structure

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The ‘net_device’ structure A look at the main kernel-object concerned with a Linux system’s network interface controller

  2. ‘data consolidation’ • Experienced software developers usually employ a ‘locality of reference’ strategy to simplify design and maintenance of code • This principle says: Things which logically are related should be kept together • Accordingly, all the information that the system needs to keep track of about a network interface is put into a single struct

  3. ‘struct net_device’ dev_base_head next prev struct net_device struct net_device struct net_device lo eth0 eth1 About 90 separate fields belong to each ‘net_device’ member of this doubly-linked list

  4. A few examples… struct net_device { char name[ IFNAMSIZ ]; int ifindex; \ /* inteface index */ unsigned int mtu; /* maximum transmission unit */ unsigned char dev_addr[ MAX_ADDR_LEN ]; /* hardware address */ void *ip_pointer; /* points to IF’s IPv4 specific data */ unsigned int flags; unsigned long trans_start; /* time (in jiffies) of last transmission */ struct net_device_stats stats; /* a default set of device statistics */ … // some function-pointers (i.e., these are ‘virtual’ functions) int (*open)( struct net_device * ); int (*stop)( struct net_device * ); int (*hard_start_xmit)( struct sk_buff *, struct net_device * ); int (*get_stats)( struct net_device * ); … };

  5. An analogy? • The ‘struct net_device’ kernel-objects play a similar role for network device-drivers as is played by ‘struct file_operations’ objects with regard to character device-drivers… • This analogy isn’t perfect (i.e., key differences) struct file_operations struct net_device open() release() write() read() llseek() ioctl() … open() stop() hard_start_xmit() get_stats() set_mac_address() do_ioctl() …

  6. ‘struct net_device_stats’ • Notice that the ‘net_device’ object contains a sub-structure for storing device statistics struct net_device_stats { unsigned long rx_packets; /* total packets received */ unsigned long tx_packets; /* total packets transmitted */ unsigned long rx_bytes; /* total bytes received */ unsigned long tx_bytes; /* total bytes transmitted */ unsigned long rx_errors; /* bad packets received */ unsigned long tx_errors; /* packet transmit problems */ … };

  7. ‘struct sk_buff’ • Notice that the ‘net_device’ object also has a member-field which can hold a pointer to to a kernel-object of type ‘struct sk_buff’ struct sk_buff skb packet data

  8. Kernel’s header-files • The kernel is written in C (with occasional uses of some ‘inline’ assembly language) • All the source-code for our Linux kernel is in this system directory: </usr/src/linux> • Most header-files are in <…/include/linux> • Those header-files that are CPU-specific are in <…/include/asm>

  9. Our directory tree… / sbin bin usr home include src web ifconfig … lsmod insmod rmmod … linux ping … cat echo ls vi dmesg … include cruse linux asm cs686 netdevice.h if.h … module.h pci.h … … io.h uaccess.h unistd.h … our course demos

  10. <linux/netdevice.h> • This is the header-file where you will find the ‘struct net_device’ definition (and the ‘struct net_device_stats’ definition as well) • And if you want to see how ‘struct sk_buff’ is defined, then look in <linux/skbuff.h> • NOTE: The kernel developers often move structure-definitions to different headers in new versions of the kernel source-code

  11. Our ‘netdevs.c’ module • We can create a Loadable Kernel Module that lets us see current information stored in the kernel’s data-structures • Our example-module ‘netdevs.c’ does this • It needs a special command-sequence to be compiled, then a special command to be installed as a ‘live’ add-on our running Linux operating system’s kernel

  12. ‘mmake.cpp’ • You can download this utility-program from our cs686 website and compile it with g++, like this: $ cp /home/web/cruse/cs686/mmake.cpp . $ g++ mmake.cpp –o mmake • Then you can use it to automate the steps required for compiling an LKM, like this: $ ./mmake netdevs

  13. ‘/sbin/insmod’ • When you have compiled our ‘netdevs.c’ source-file, you will have a kernel-object file named ‘netdevs.ko’ and you can use the ‘insmod’ command to install it: $ /sbin/insmod netdevs.ko • When it is installed, this LKM creates a pseudo-file (in the ‘/proc’ directory) that you can send to your screen with ‘cat’: $ cat /proc/netdevs

  14. ‘/sbin/rmmod’ • If you decide you would like to modify the output from your ‘/proc/netdevs’ file, you can remove ‘netdevs.ko’ from the kernel, edit the module’s source-code, recompile the ‘netdevs.c’ file with ‘mmake’, and then install the new version of ‘netdevs.ko’: $ /sbin/rmmod netdevs.ko

  15. In-class exercise #1 • Modify the output shown by ‘/proc/netdevs’ so that the current state of each interface (i.e., UP or DOWN) will get displayed • HINT: The kernel uses a status-bit in the ‘flags’ field of a ‘struct net_device’ object to keep track of whether the device is now ‘up’ or ‘down’ (compare ‘/sbin/ifconfig –a) • Look in the header-file <linux/if.h> to find out how bits of the ‘flags’ field are used

  16. Two coding approaches… • One way to write your solution for in-class exercise #1 is to add a line like this: • But a different solution which produces the same effect avoids the ‘if-else’ construct: if ( dev->flags & IFF_UP ) len += sprintf( buf+len, “UP” ); else len += sprintf( buf+len, “DOWN “ ); char *state[ 2 ] = { “DOWN”, “UP” }; // an array of string-pointers … len += sprintf( buf+len, “%s”, state[ dev->flags & IFF_UP ] ); …

  17. In-class exercise #2 • Look at the output produced when you execute the Linux ‘ifconfig’ program • Choose some added item of information about our station’s network interfaces (from the ‘ifconfig’ output) and see if you can enhance our ‘netdevs.c’ demo so it’s pseudo-file will display that extra item of information (e.g., dev->stats.tx_bytes)

More Related