关于dev_queue_xmit

zysmiracle 2009-03-27 02:24:14
我的2440板子上有两块网卡,我想把eth0接收到的内容转发到eth1,具体做法如下

我在net_if中接收到skb的数据包, 拨去原接口的frame, 然后重新封装另一个接口的frame,最后用 dev_queue_xmit转发出去,
skb中的dev也设置过了, 最后的结果就是, 我用ping命令测试没有任何问题, 但是如果传输的数据量过大,
内核就会提示:, status check failed: (num)
(num)就是一个数字, 出现过的有195, 78, 35, 等等, 随机性非常的大,

这到底是什么问题, 小弟先谢过版主和各位大侠,

这个问题困扰了我好几天了, 去网上查了好多, 都找不到相关的问题, 还请各位大侠帮帮忙
...全文
1054 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
windboy_linux 2009-04-18
  • 打赏
  • 举报
回复
我觉得ping是ICMP协议,而FTP用的是TCP协议,这两个协议在linux内核中的处理很不一样
我觉得你可以查一下这两个协议的处理流程
morris88 2009-04-15
  • 打赏
  • 举报
回复
楼主还是重新开贴吧...
zysmiracle 2009-04-15
  • 打赏
  • 举报
回复
兄弟,看见你发的帖子了,你是用netfilter的吧,我也是要实现包转发

内核在原则上也不会给你调用驱动程序, 所以我发数据是用dev_queue_xmit
有人说它们用 dev->hard_start_xmit,这是一个函数指针,它指向驱动程序的发送函数,
你可以试试,它在初始化的时候被赋值的,你可以试试

还有就是,帮帮忙,看看我的问题怎么解决
chenzijing 2009-04-15
  • 打赏
  • 举报
回复
楼主还是重新开贴,把问题总结一下,帖子太多比较乱!我那边也准备重开
zysmiracle 2009-04-13
  • 打赏
  • 举报
回复
自己up一下
chenzijing 2009-04-13
  • 打赏
  • 举报
回复
楼主,你那netif_rx处怎么把包送到另一网卡的发送函数的?
chenzijing 2009-04-13
  • 打赏
  • 举报
回复
兄弟,顶一下
xxgamexx 2009-04-03
  • 打赏
  • 举报
回复
关注! 学习!
zysmiracle 2009-04-01
  • 打赏
  • 举报
回复
先感谢morris88这几天的帮助, 出错的地方我已经明白,
但是我还想问下, 是什么情况导致 dumy register的内容为不是0或1

今天又测试过了, 我用ping程序发送1000多个包都没有出现status check failed, 但是用ftp传数据就会有

1. 是不是不能在netif_rx函数中,调用dev_queue_xmit
2. 如果能调用, 需要注意什么, 设置什么
3. 如果不能调用, 应该在 接收 的什么时候调用dev_queue_xmit

只要能解决问题, 分不够可以再加
morris88 2009-03-31
  • 打赏
  • 举报
回复

/*
* Received a packet and pass to upper layer
*/
static void
dm9000_rx(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
struct dm9000_rxhdr rxhdr;
struct sk_buff *skb;
u8 rxbyte, *rdptr;
bool GoodPacket;
int RxLen;

/* Check packet ready or not */
do {
ior(db, DM9000_MRCMDX); /* Dummy read */

/* Get most updated data */
rxbyte = readb(db->io_data);

/* Status check: this byte must be 0 or 1 */
if (rxbyte > DM9000_PKT_RDY) {
printk("status check failed: %d\n", rxbyte);
iow(db, DM9000_RCR, 0x00); /* Stop Device */
iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */
return;
}

if (rxbyte != DM9000_PKT_RDY)
return;

/* A packet ready now & Get status/length */
GoodPacket = true;
writeb(DM9000_MRCMD, db->io_addr);

(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));


morris88 2009-03-31
  • 打赏
  • 举报
回复
兄弟,驱动里面实现就是:当接收报文时,先读一个dumy register,如果该寄存器的内容为0、1就正常接收报文,如果为其他就打印上面提到的那个信息,你括弧里面的num就是该dumy_register里读出的内容。
即使你只发送报文,那么对方收到报文后就会根据协议给你的网卡返回对应的协议报文。

而在发送报文时,驱动是不会打印这个消息的。

zysmiracle 2009-03-31
  • 打赏
  • 举报
回复
哪位大侠再给说说,小弟先谢过了
zysmiracle 2009-03-30
  • 打赏
  • 举报
回复
我是在发送时出现的问题, 问题没有解决,

up
morris88 2009-03-28
  • 打赏
  • 举报
回复
这个信息是由驱动提供的;Num = 0, 1表示接收OK,而其他的表示在接收报文发现异常。以太网产生异常的原因有很多。
zysmiracle 2009-03-28
  • 打赏
  • 举报
回复
2.6.14
morris88 2009-03-28
  • 打赏
  • 举报
回复
linux kernel版本?
zysmiracle 2009-03-28
  • 打赏
  • 举报
回复
没有,只是重新只了nh.raw指针, 我想应该是没错, 如果有问题,不应该能ping的通
morris88 2009-03-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zysmiracle 的回复:]
因为我重新封装了帧, 所以应该是路由方式,
至于skb的其他参数是否需要设置, 我也不是很清楚, 所以想请教以下, 看是什么的问题

ps: 对于skb我设置了len, mac.raw, nh.raw
[/Quote]

意思是修改了IP头?
zysmiracle 2009-03-28
  • 打赏
  • 举报
回复
因为我重新封装了帧, 所以应该是路由方式,
至于skb的其他参数是否需要设置, 我也不是很清楚, 所以想请教以下, 看是什么的问题

ps: 对于skb我设置了len, mac.raw, nh.raw
zysmiracle 2009-03-28
  • 打赏
  • 举报
回复
因为我重新封装了帧, 所以应该是路由方式,
至于skb的其他参数是否需要设置, 我也不是很清楚, 所以想请教以下, 看是什么的问题

加载更多回复(2)
内容概要:本文详细探讨了Linux网络设备的数据发送原理,涵盖从应用层到物理层的全过程。文章首先介绍了Linux在网络中的重要性,随后逐步解析了数据在各层协议间的传递:应用层通过socket API将数据传递给传输层,传输层根据TCP或UDP协议处理数据,网络层通过IP协议分配地址并选择路由,网络接口层将数据封装成帧并通过网络设备发送。关键函数如dev_queue_xmit、__dev_xmit_skb和dev_hard_start_xmit分别负责数据的预处理、拥塞控制和直接发送。此外,文章还详细解释了sk_buff数据结构和队列规则(Qdisc)的作用,以及拥塞控制机制。最后通过ping命令和UDP网络服务两个实例,展示了数据发送的实际应用过程。 适合人群:具备一定Linux基础和网络知识的技术人员,特别是对Linux网络设备和数据传输感兴趣的开发人员和运维工程师。 使用场景及目标:①理解Linux网络设备的工作原理,提升网络性能优化和故障排查能力;②掌握数据在各层协议间的传递过程,深入了解网络通信机制;③学习关键函数和数据结构的运作方式,为开发高效网络应用程序提供理论支持。 阅读建议:本文内容较为深入,建议读者结合实际网络环境进行实验,通过抓包工具(如Wireshark)观察数据包的变化,加深对各层协议和关键函数的理解。同时,读者可以尝试编写简单的网络程序,如ping命令或UDP服务,亲身体验数据发送的全过程。

4,465

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧