linux内核 网络模块,linux内核网络模块初探测

内核版本smdk 2.6.28.6

代码功能,编译后,形成test.ko,开发板加载模块后,出现结果:

===========================================

/ # lsmod

/ # insmod test.ko

/ # lsmod

test 2912 0 - Live 0xbf000000

/ # ifconfig -a

eth0      Link encap:Ethernet  HWaddr 00:E0:4A:BC:15:E7

inet addr:192.168.10.20  Bcast:192.168.10.255  Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

RX packets:1811 errors:0 dropped:0 overruns:0 frame:0

TX packets:750 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:2311076 (2.2 MiB)  TX bytes:125320 (122.3 KiB)

Interrupt:108 Base address:0x300

lo        Link encap:Local Loopback

inet addr:127.0.0.1  Mask:255.0.0.0

UP LOOPBACK RUNNING  MTU:16436  Metric:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

sx        Link encap:Local Loopback

LOOPBACK  MTU:16436  Metric:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #

===========================================

代码如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include /* For the statistics structure. */

#include /* For ARPHRD_ETHER */

#include

#include

#include

#include

#include

struct pcpu_lstats {

unsigned long packets;

unsigned long bytes;

};

extern int register_pernet_device(struct pernet_operations *ops);

// extern const struct header_ops eth_header_ops;

const struct header_ops eth_header_ops ____cacheline_aligned = {

.create= eth_header,

.parse= eth_header_parse,

.rebuild= eth_rebuild_header,

.cache= eth_header_cache,

.cache_update= eth_header_cache_update,

};

/*

* The higher levels take care of making this non-reentrant (it's

* called with bh's disabled).

*/

static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)

{

struct pcpu_lstats *pcpu_lstats, *lb_stats;

skb_orphan(skb);

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

dev->last_rx = jiffies;

/* 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());

lb_stats->bytes += skb->len;

lb_stats->packets++;

netif_rx(skb);

return 0;

}

static struct net_device_stats *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;

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;

}

stats->rx_packets = packets;

stats->tx_packets = packets;

stats->rx_bytes = bytes;

stats->tx_bytes = bytes;

return stats;

}

static u32 always_on(struct net_device *dev)

{

return 1;

}

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,

};

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;

}

static void loopback_dev_free(struct net_device *dev)

{

struct pcpu_lstats *lstats = dev->ml_priv;

free_percpu(lstats);

free_netdev(dev);

}

/*

* The loopback device is special. There is only one instance

* per network namespace.

*/

static void loopback_setup(struct net_device *dev)

{

dev->get_stats= &get_stats;

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

dev->hard_start_xmit= loopback_xmit;

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

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

dev->tx_queue_len= 0;

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

dev->flags= IFF_LOOPBACK;

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;

dev->ethtool_ops= &loopback_ethtool_ops;

dev->header_ops= &eth_header_ops;

dev->init = loopback_dev_init;

dev->destructor = loopback_dev_free;

}

/* Setup and register the loopback device. */

static __net_init int loopback_net_init(struct net *net)

{

struct net_device *dev;

int err;

err = -ENOMEM;

dev = alloc_netdev(0, "sx", 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;

}

static __net_exit void loopback_net_exit(struct net *net)

{

struct net_device *dev = net->loopback_dev;

unregister_netdev(dev);

}

static struct pernet_operations __net_initdata loopback_net_ops = {

.init = loopback_net_init,

.exit = loopback_net_exit,

};

static int __init loopback_init(void)

{

return register_pernet_device(&loopback_net_ops);

}

/* Loopback is special. It should be initialized before any other network

* device and network subsystem.

*/

fs_initcall(loopback_init);

// module_init(loopback_init);

module_exit(loopback_net_exit);

MODULE_LICENSE("GPL");

好的,今日实验到此结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值