Hands-on ethernet driver
Transcript of Hands-on ethernet driver
![Page 2: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/2.jpg)
2
Agenda
• Introduction
• Data structure of network stack
• A brief look at linux ethernet driver
• Tips for linux ethernet driver
![Page 3: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/3.jpg)
3
Basic layers of the network stack
![Page 4: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/4.jpg)
4
IEEE 802.3 frame vs. Ethernet II
https://www.safaribooksonline.com/library/view/junos-enterprise-switching/9780596804244/ch01.html
![Page 5: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/5.jpg)
5
net_device structure
• Defined in the <include/linux/netdevice.h>
• This structure represents a network interface
• Doubly-linked list all net_device
• Allocation with alloc_netdev()
• alloc_etherdev() is a specialization of alloc_netdev() for ethernet interfaces
![Page 6: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/6.jpg)
6
sk_buff structure
• Defined in the <include/linux/skbuff.h>
• The socket buffer, is the most fundamental data structure in the Linux networking code
• A doubly linked list
• Every packet sent or received is handled using this data structure
• Allocation with dev_alloc_skb()
![Page 7: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/7.jpg)
7
Interact between NIC device and Kernel
• Polling‒ Kernel side check the device constantly if new data is
available
• Interrupt‒ NIC informs the kernel when frame is received
‒ Transmission complete, transmission error
• NAPI (New API)‒ A mix of polling and interrupts mode
![Page 8: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/8.jpg)
8
Reception / Transmission
Eth0
skb → protocolnetif_rx/netif_rx_schedule
do_softirq / NET_RX_ACTION
netif_receive_skb
ip_rcv
hard_start_xmit
dev_queue_xmit
Traffic Control
RX TX
IRQ
L3
Driver
![Page 9: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/9.jpg)
9
Linux kernel module example
#include <linux/module.h> /* Needed by all modules */#include <linux/kernel.h> /* Needed for KERN_INFO */#include <linux/init.h> /* Needed for the macros */
static int __init init_hello(void){
printk(KERN_INFO "Hello, world !\n");return 0;
}
static void __exit cleanup_hello(void){
printk(KERN_INFO "Goodbye, world !\n");}
module_init(init_hello);module_exit(cleanup_hello);
MODULE_LICENSE("GPL");MODULE_AUTHOR("David Chang"); /* Who wrote this module? */MODULE_DESCRIPTION("Simple Hello World");/* What does this module do */
![Page 10: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/10.jpg)
10
An sample ethernet driver layout#include <linux/module.h>#include <linux/init.h> #include <linux/netdevice.h>
static struct net_device *dev;static struct net_device_stats *stats;…
labnet_open()
labnet_close()
labnet_setup()
labnet_start_xmit()
labnet_get_stats()
labnet_init()
labnet_exit()
![Page 11: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/11.jpg)
11
labnet_init()
static int __init labnet_init(void){ dev = alloc_netdev(0, "labnet%d", NET_NAME_UNKNOWN, labnet_setup); if (register_netdev(dev)) { pr_info("Register netdev failed!\n"); free_netdev(dev); return -1; } return 0;}
![Page 12: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/12.jpg)
12
labnet_exit()
static void __exit labnet_exit(void){ unregister_netdev(dev); free_netdev(dev);}
![Page 13: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/13.jpg)
13
labnet_setup()
static void labnet_setup(struct net_device *dev){ int i; /* Assign the MAC address */ for (i = 0; i < ETH_ALEN; ++i) { dev->dev_addr[i] = (char)i; }
ether_setup(dev); dev->netdev_ops = &ndo; dev->flags |= IFF_NOARP; stats = &dev->stats;}
![Page 14: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/14.jpg)
14
net_device_ops
static struct net_device_ops ndo = { .ndo_open = labnet_open, .ndo_stop = labnet_close, .ndo_start_xmit = labnet_start_xmit, .ndo_do_ioctl = labnet_do_ioctl, .ndo_get_stats = labnet_get_stats,};
![Page 15: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/15.jpg)
15
labnet_open()
static int labnet_open(struct net_device *dev){ netif_start_queue(dev); return 0;}
![Page 16: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/16.jpg)
16
labnet_close()
static int labnet_close(struct net_device *dev){ netif_stop_queue(dev); return 0;}
![Page 17: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/17.jpg)
17
labnet_start_xmit()
static int labnet_start_xmit(struct sk_buff *skb, struct net_device *dev){ int len; char *data; len = skb->len; data = skb->data; dev->trans_start = jiffies; /* save the timestamp */
stats->tx_packets += 1; stats->tx_bytes += skb->len; /* actual deliver of data is device-specific */ hw_tx(data, len, dev); /* loopback it to receive */ labnet_rx(skb, dev);
return 0;}
![Page 18: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/18.jpg)
18
labnet_rx()
static void labnet_rx(struct sk_buff *skb, struct net_device *dev){ stats->rx_packets += 1; stats->rx_bytes += skb->len; skb->protocol = eth_type_trans( skb, dev ); netif_rx(skb);}
![Page 19: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/19.jpg)
19
Virtual / Real network device
• Each network device is represented by a instance of net_device structure
• Virtual Devices:‒ Build on top of a real (or virtual) device
‒ Bonding, VLAN (802.1Q), Bridging, Aliasing interface, IP over IP (IPIP), GRE
‒ Similar handling like real devices (register device et cetera)
![Page 20: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/20.jpg)
20
Statistic
• ip -s -s link show eth0
• netstat -s (statistics for each protocol)
• ethtool -S eth0
• /sys/class/net/eth0/statistics/3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether f0:de:f1:19:20:57 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 12094943228 10939498 0 265160 0 27052 RX errors: length crc frame fifo missed 0 0 0 0 10535 TX: bytes packets errors dropped carrier collsns 651092971 6667618 0 0 0 0 TX errors: aborted fifo window heartbeat transns 0 0 0 0 164
![Page 21: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/21.jpg)
21
Another way
• /proc/net: various networking parameters and statistics
• /proc/sys/net: concerning various networking topics
• /sys/class/net: The class directory contains representations of every device class that is registered with the kernel.
![Page 22: Hands-on ethernet driver](https://reader034.fdocuments.in/reader034/viewer/2022042600/58ae83f11a28abea4f8b6709/html5/thumbnails/22.jpg)
22
Thank you!