The Net - Device' Structure: A Look at The Main Kernel-Object Concerned With A Linux System's Network Interface Controller

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 17

The net_device structure

A look at the main kernel-object


concerned with a Linux systems
network interface controller
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
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
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 IFs 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 * );

};
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
struct file_operations struct net_device
open() open()
release() stop()
write() hard_start_xmit()
read() get_stats()
llseek() set_mac_address()
ioctl() do_ioctl()

This analogy isnt perfect (i.e., key differences)


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 */

};
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
Kernels 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>
Our directory tree
/

sbin bin usr home


include src
web
ifconfig ping linux

lsmod cat include cruse
insmod echo
rmmod ls linux asm
vi cs686
dmesg
netdevice.h
io.h
if.h our
uaccess.h
course
module.h unistd.h
demos
pci.h

<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
Our netdevs.c module
We can create a Loadable Kernel Module
that lets us see current information stored
in the kernels 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 systems kernel
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
/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
/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 modules source-code, recompile
the netdevs.c file with mmake, and then
install the new version of netdevs.ko:
$ /sbin/rmmod netdevs.ko
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
Two coding approaches
One way to write your solution for in-class
exercise #1 is to add a line like this:
if ( dev->flags & IFF_UP )
len += sprintf( buf+len, UP );
else len += sprintf( buf+len, DOWN );

But a different solution which produces the


same effect avoids the if-else construct:
char *state[ 2 ] = { DOWN, UP }; // an array of string-pointers


len += sprintf( buf+len, %s, state[ dev->flags & IFF_UP ] );

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

You might also like