Linux的网络驱动中,lookback 驱动算是最为简单的。本次分析的程序来自 Linux-2.6.32.68 源码,其中 lookback.c 驱动程序位于 /drives/net/ 目录下。

普通的网卡驱动都是以模块化注册到系统的,但是 lookback 驱动是和 kernel 一体的,Linux在启动的时候会调用 lookback 驱动。

1、设备注册

lookback网络驱动接口在一个全局的网络设备列表里插入一个数据结构.每个接口由一个结构 net_device 项来描述, 它在 里定义.

net_device 结构, 如同许多其他内核结构, 包含一个 kobject,以及因此它可被引用计数并通过 sysfs 输出. 如同别的这样的结构, 它必须动态分配. 进行这种分配的内核函数是 alloc_netdev, 它有下列原型:

struct net_device *alloc_netdev(

int sizeof_priv,

const char *name,

void (*setup)(struct net_device*));

sizeof_priv 是驱动的的"私有数据"区的大小;name 是这个接口的名字;setup是一个初始化函数的指针, 被调用来设置 net_device结构的剩余部分。

net_device 结构完成初始化之后,接着传递这个结构给 register_netdev 完成设备的注册。

/* Setup and register the loopback device. */

static __net_init int loopback_net_init(struct net *net)

{

struct net_device *dev;

int err;

err = -ENOMEM;

//初始化net_device 结构

dev = alloc_netdev(0, "lo", loopback_setup);

if (!dev)

goto out;

//设置网络命名空间

dev_net_set(dev, net);

//注册网络设备

err = register_netdev(dev);

if (err)

goto out_free_netdev;

net->loopback_dev = dev;

return 0;

out_free_netdev:

free_netdev(dev);

out:

if (net == &init_net)

panic("loopback: Failed to register netdevice: %d\n", err);

return err;

}

Lookback驱动中初始化net_device 结构语句:

dev = alloc_netdev(0, "lo", loopback_setup)

初始化函数为loopback_setup

static void loopback_setup(struct net_device *dev)

{

//最大传输单元

dev->mtu= (16 * 1024) + 20 + 20 + 12;

//硬件头部长度,被发送报文在 IP 头之前的字节数。对于以太网接口值为14

dev->hard_header_len= ETH_HLEN;/* 14*/

//硬件 (MAC) 地址长度。以太网地址长度是 6 个字节

dev->addr_len= ETH_ALEN;/* 6*/

//设备发送队列中可以排队的最大帧数

dev->tx_queue_len= 0;

//接口的硬件类型,类型定义于

dev->type= ARPHRD_LOOPBACK;/* 0x0001*/

//接口标志。IFF_LOOPBACK这个标志只在环回接口中设置. 内核检查 IFF_LOOPBACK , 以代替硬连线 lo

dev->flags= IFF_LOOPBACK;

dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;

dev->features = NETIF_F_SG | NETIF_F_FRAGLIST

| NETIF_F_TSO

| NETIF_F_NO_CSUM

| NETIF_F_HIGHDMA

| NETIF_F_LLTX

| NETIF_F_NETNS_LOCAL;

// 声明对 ethtool 支持

dev->ethtool_ops= &loopback_ethtool_ops;

dev->header_ops= ð_header_ops;

dev->netdev_ops= &loopback_ops;

dev->destructor= loopback_dev_free;

}

ethtool 是一个实用工具, 提供大量控制网络接口的操作。对 ethtool 支持的相关声明可在 中找到. 它的核心是一个 ethtool_ops类型的结构, 里面包含一个全部 24 个不同方法来支持 ethtool.

static const struct ethtool_ops loopback_ethtool_ops = {

.get_link= always_on,

.set_tso= ethtool_op_set_tso,

.get_tx_csum= always_on,

.get_sg= always_on,

.get_rx_csum= always_on,

};

初始化函数中,loopback_dev_free释放了 net_device 结构,一旦已调用了free_netdev, 将再不能对个设备或者私有数据做任何引用。

static void loopback_dev_free(struct net_device *dev)

{

struct pcpu_lstats *lstats = dev->ml_priv;

free_percpu(lstats);

free_netdev(dev);

网络驱动中,还声明了一些能够操作它的函数:

static const struct net_device_ops loopback_ops = {

.ndo_init = loopback_dev_init,

.ndo_start_xmit= loopback_xmit,

.ndo_get_stats = loopback_get_stats,

};

其中loopback_dev_init 用于设备初始化

static int loopback_dev_init(struct net_device *dev)

{

struct pcpu_lstats *lstats;

lstats = alloc_percpu(struct pcpu_lstats);

if (!lstats)

return -ENOMEM;

dev->ml_priv = lstats;

return 0;

}

loopback_xmit用于发送报文

static netdev_tx_t loopback_xmit(struct sk_buff *skb,

struct net_device *dev)

{

struct pcpu_lstats *pcpu_lstats, *lb_stats;

int len;

skb_orphan(skb);

//帮助函数( eth_type_trans ), 用于发现一个合适值来赋给 protocol

skb->protocol = eth_type_trans(skb, dev);

/* it's OK to use per_cpu_ptr() because BHs are off */

pcpu_lstats = dev->ml_priv;

lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());

len = skb->len;

if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {

lb_stats->bytes += len;

lb_stats->packets++;

} else

lb_stats->drops++;

return NETDEV_TX_OK;

}

loopback_get_stats用于获取接口的统计信息

static struct net_device_stats *loopback_get_stats(struct net_device *dev)

{

const struct pcpu_lstats *pcpu_lstats;

struct net_device_stats *stats = &dev->stats;

unsigned long bytes = 0;

unsigned long packets = 0;

unsigned long drops = 0;

int i;

pcpu_lstats = dev->ml_priv;

for_each_possible_cpu(i) {

const struct pcpu_lstats *lb_stats;

lb_stats = per_cpu_ptr(pcpu_lstats, i);

bytes += lb_stats->bytes;

packets += lb_stats->packets;

drops += lb_stats->drops;

}

stats->rx_packets = packets;

stats->tx_packets = packets;

stats->rx_dropped = drops;

stats->rx_errors = drops;

stats->rx_bytes = bytes;

stats->tx_bytes = bytes;

return stats;

}

2、设备注销

调用了unregister_netdev函数,注销一个网络设备。

static __net_exit void loopback_net_exit(struct net *net)

{

struct net_device *dev = net->loopback_dev;

unregister_netdev(dev);

}

linux网络驱动lookback,Linux lookback驱动分析相关推荐

  1. Linux网络编程篇之ICMP协议分析及ping程序实现

    Linux网络编程系列: Linux网络编程篇之Socket编程预备知识 Linux网络编程篇之TCP协议分析及聊天室功能实现 如果对Linux网络编程,对socket通信不是太清楚的同学,强烈推荐看 ...

  2. linux 网络使用log,linux 网络命令last、lastlog、traceroute、netstat

    last /usr/bin/last 语法:last 功能:列出目前与过去登入系统的用户信息 reboot 是重启信息 lastlog lastlog -u 502(用户ID) traceroute ...

  3. linux网络驱动架构,Linux网络体系架构和网卡驱动设计

    Linux网络体系架构 1.Linux的协议栈层次 2.Linux的网络子系统架构 Linux的协议栈层次 Linux的优点之一在于它丰富而稳定的网络协议栈.其范围从协议无关层(例如通用socket层 ...

  4. Linux网络协议栈:网卡收包分析

    Table of Contents 网卡收包 一,框架 二,初始化 三,驱动收包 四,内核处理 参考文章 推荐阅读 网卡收包 内核网络模块如何初始化? 内核如何通过网卡驱动收发数据包? 驱动收到的数据 ...

  5. linux 虚拟机大量udp请求失败_理解 Linux 网络栈:Linux 网络协议栈简单总结分析...

    1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linu ...

  6. 理解 Linux 网络栈:Linux 网络协议栈简单总结

    1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linu ...

  7. linux网络编程 ppt,LINUX网络编程.ppt

    <LINUX网络编程.ppt>由会员分享,可在线阅读,更多相关<LINUX网络编程.ppt(47页珍藏版)>请在人人文库网上搜索. 1.LINUX网络编程,行业事业部 黄文举 ...

  8. kali linux 网络架构,Kali Linux网络扫描教程大学霸内部资料

    Kali Linux网络扫描教程大学霸内部资料 Kali Linux网络扫描教程大学霸内部资料 黑白教程:95元 彩色教程:118元 介绍:渗透测试是一门操作性极强的学科.掌握该技能的最佳方式就是大量 ...

  9. linux网络协议栈招聘,Linux 网络协议栈开发(一)ping命令

    linux网络开发中比较常用的命令之一是ping,最近一直再查rtl的模块连接问题,使用ping命令后一段时间,模块就卡主了感觉,不能完成基本的网络通信了,所以来查一查,我通常使用了ping命令加上要 ...

  10. linux 网络端口状态,Linux下用netstat查看网络状态、端口状态(转)

    转:http://blog.csdn.net/guodongdongnumber1/article/details/11383019 在linux一般使用netstat 来查看系统端口使用情况步. n ...

最新文章

  1. 【二次元stylus解放css】用stylus画可爱的小丸子
  2. 贝叶斯定理的实际应用
  3. c 中ajax不起作用,Jquery AJAX調用:$(this)在成功后不起作用
  4. MySQL学习(十五)
  5. 【AI白身境】学AI必备的python基础
  6. mysql fetch lengths_php mysqli_fetch_lengths()函数
  7. 利用mochiweb让服务端主动推送数据至前端页面
  8. RecyclerView实现滑动删除和拖拽功能
  9. 数据库搭建主从mysql_数据库mysql主从搭建
  10. centos7火狐浏览器上不了网_网络问题备忘:能ping通,就是上不了网
  11. Metadata Lock原理5
  12. 图层重命名快捷键_实际操作,在PS中如何批量给图层重命名并导出
  13. 【计算机视觉40例】案例14:指纹识别
  14. Oracle 运维篇+进程追踪调试(AIX系统)
  15. 微信支付-同一个订单多次请求(生成二维码)方案
  16. cad断点快捷键_史上最好的CAD常用快捷键及使用方法集
  17. video在iPhone浏览器上播放没有声音
  18. 常用室内定位技术总结
  19. PostQuitMessage
  20. Atari 2600 新书:主机游戏的一次黎明冒险

热门文章

  1. 密码学相关基础二(非对称加密和数字签名篇)
  2. Exchange邮件筛选技术
  3. 只需要努力,其他的都交给时光----三级网络学习总结
  4. 香农的“创意思维在编程的应用
  5. 导频、SIC串行干扰抵消
  6. python语音对话查询起始路和目的地_查询通话记录详情
  7. 出错信息:Incorrect string value: '\xE4\xBD\xA0\xE5\xA5\xBD' for column 'username'
  8. plink --extract参数采坑问题记录
  9. H.266/VVC代码学习21:帧内角度预测的实现 / 近对角模式的PDPC(xPredIntraAng)
  10. 139邮箱java版下载_139邮箱手机版下载-139邮箱手机客户端下载 8.9.1-领航下载站