一、loopback
协议栈需要发送数据时,将数据发送给网卡,网卡通过介质发送。而loopback回环网卡,是自发自收的。
二、代码分析
-
/*
-
* INET An implementation of the TCP/IP protocol suite for the LINUX
-
* operating system. INET is implemented using the BSD Socket
-
* interface as the means of communication with the user level.
-
*
-
* Pseudo-driver for the loopback interface.
-
*
-
* Version: @(#)loopback.c 1.0.4b 08/16/93
-
*
-
* Authors: Ross Biro
-
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-
* Donald Becker, <becker@scyld.com>
-
*
-
* Alan Cox : Fixed oddments for NET3.014
-
* Alan Cox : Rejig for NET3.029 snap #3
-
* Alan Cox : Fixed NET3.029 bugs and sped up
-
* Larry McVoy : Tiny tweak to double performance
-
* Alan Cox : Backed out LMV's tweak - the linux mm
-
* can't take it...
-
* Michael Griffith: Don't bother computing the checksums
-
* on packets received on the loopback
-
* interface.
-
* Alexey Kuznetsov: Potential hang under some extreme
-
* cases removed.
-
*
-
* This program is free software; you can redistribute it and/or
-
* modify it under the terms of the GNU General Public License
-
* as published by the Free Software Foundation; either version
-
* 2 of the License, or (at your option) any later version.
-
*/
-
#include <linux/kernel.h>
-
#include <linux/jiffies.h>
-
#include <linux/module.h>
-
#include <linux/interrupt.h>
-
#include <linux/fs.h>
-
#include <linux/types.h>
-
#include <linux/string.h>
-
#include <linux/socket.h>
-
#include <linux/errno.h>
-
#include <linux/fcntl.h>
-
#include <linux/in.h>
-
#include <linux/init.h>
-
-
#include <asm/system.h>
-
#include <asm/uaccess.h>
-
#include <asm/io.h>
-
-
#include <linux/inet.h>
-
#include <linux/netdevice.h>
-
#include <linux/etherdevice.h>
-
#include <linux/skbuff.h>
-
#include <linux/ethtool.h>
-
#include <net/sock.h>
-
#include <net/checksum.h>
-
#include <linux/if_ether.h> /* For the statistics structure. */
-
#include <linux/if_arp.h> /* For ARPHRD_ETHER */
-
#include <linux/ip.h>
-
#include <linux/tcp.h>
-
#include <linux/percpu.h>
-
#include <net/net_namespace.h>
-
-
unsigned long bytes = 0;
-
unsigned long packets = 0;
-
struct net_device *dev; //创建net_device结构
-
-
int loopback_xmit(struct sk_buff *skb, struct net_device *dev) //发送函数
-
{
-
skb->protocol = eth_type_trans(skb, dev); //获取网络包协议
-
-
bytes += skb->len; //获取数据包的长度
-
packets++; //包的量
-
-
netif_rx(skb); //发送skb信息
-
-
return 0;
-
}
-
-
struct net_device_stats *loopback_get_stats(struct net_device *dev) //获取状态
-
{
-
struct net_device_stats *stats = &dev->stats;
-
-
stats->rx_bytes = bytes;
-
stats->tx_bytes = bytes;
-
stats->rx_packets = packets;
-
stats->tx_packets = packets;
-
-
return &stats;
-
}
-
-
struct net_device_ops loopback_ops = //net_device_ops是回环网卡的函数结构指针
-
{
-
.ndo_start_xmit = loopback_xmit,
-
.ndo_get_stats = loopback_get_stats,
-
};
-
-
void loopback_setup(struct net_device *dev)
-
{
-
dev->mtu = (16*1024)+20+20+12; //16kB+tcp+ip+net,设置最大的空间
-
dev->flags = IFF_LOOPBACK; //表明是loopback函数
-
dev->header_ops = ð_header_ops; //使用默认的header_ops
-
dev->netdev_ops = &loopback_ops; //使用自定义的netdev_ops
-
}
-
-
/* Setup and register the loopback device. */
-
static __net_init int loopback_net_init(struct net *net)
-
{
-
int err = -ENOMEM;
-
-
//1.
-
dev = alloc_netdev(0, "lo", loopback_setup); //给dev分配空间,0是自定义内容大小,lo是显示的名字,loopback_setup是初始化函数
-
-
//4.
-
err = register_netdev(dev); //注册dev
-
-
net->loopback_dev = dev;
-
-
return 0;
-
}
-
-
static __net_exit void loopback_net_exit(struct net *net)
-
{
-
-
unregister_netdev(dev); //注销dev结构
-
}
-
-
/* Registered in net/core/dev.c */
-
struct pernet_operations __net_initdata loopback_net_ops = {
-
.init = loopback_net_init,
-
.exit = loopback_net_exit,
-
};
阅读(728) | 评论(0) | 转发(0) |