dev_queue_xmit返回值为0,但是对端没有收到包,内核版本2.6.32

Hey_Lightman 2016-08-25 01:16:05
各位大神,小弟刚接触netfilter不久,在调用dev_queue_xmit的时候遇到了问题,返回值为0,但是对端并没有收到我发的包。
我要实现的功能是,有A,B,C三台服务器,我写的驱动模块在B中,是一台负责转发的服务器的角色,现在想做的是,A给B发一个包的时候,B能够收到两个相同的包,C到A不需要复制,我的代码如下,在测试的时候A向C发了3个icmp包,但是C只收到了3个包,而且,我抓了B和C的所有网卡,也都只有3三个包,所以我多发的那一份,并没有成功,不知道问题出现在哪里,我觉得应该是在dev_queue_xmit这个函数就没有发出去,内核版本2.6.32,希望各位大神指教。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>

#define ETH_USER "eth2"

static struct nf_hook_ops nfho;
unsigned int copy_skb_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff * sk = NULL;

printk(KERN_INFO "============================\n");

printk(KERN_INFO "EthName == %s\n", out->name);
if(0 == strcmp(out->name, ETH_USER))
{
//sk = skb_clone(skb, GFP_KERNEL);
sk = skb_copy(skb, GFP_ATOMIC & ~__GFP_DMA);

int ret = dev_queue_xmit(sk);
printk(KERN_INFO "ret == %d\n", ret);
//return NF_DROP;
}
printk(KERN_INFO "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");

return NF_ACCEPT;
}

static int __init init_nethook(void)
{
nfho.hook = copy_skb_hook;
nfho.hooknum = NF_INET_POST_ROUTING;
nfho.owner = THIS_MODULE;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
return 0;
}

static void __exit exit_nethook(void)
{
nf_unregister_hook(&nfho);
}

module_init(init_nethook);
module_exit(exit_nethook);
MODULE_AUTHOR("renzhanyi");
MODULE_LICENSE("GPL");
...全文
339 4 打赏 收藏 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hey_Lightman 2016-08-26
  • 打赏
  • 举报
回复
引用 1 楼 bitch_____ 的回复:
没搞过这个,检索了一下dev_queue_xmit,找到一篇文章,感觉对你有用http://www.mobile-open.com/2016/974079.html
你好,你知道怎么把skb中的mac打印出来么,我的内核是2.6.32,可以用eth_hdr(skb)获取到ethhdr结构体,然后在结构体中有源mac和目的mac分别是定义为unsigned char[ETH_ALINE] h_dest,不过我不管怎么打印都会导致死机,只有当按照数字打印的时候不会死机,不过按照%d或者%x打印的话,根本不是正常的mac的格式,求指教
Hey_Lightman 2016-08-25
  • 打赏
  • 举报
回复
首先谢谢一楼和二楼哈,我会好好参考你们的意见的,然后我想知道怎么给分呀,之前没用过这个。。。
zs_2016 2016-08-25
  • 打赏
  • 举报
回复

看一下这块,
需要确认的几个点就是

1.设备在调用这个函数之前,必须设置设备优先级 和缓冲区buffer

2.如果此函数发送失败,会返回一个负数的Error number,不过即使返回正数,也不一定保证发送成功,封包也许会被网络拥塞给drop掉

3.这个函数也可以从队列规则中返回error,NET_XMIT_DROP, 这个错误是一个整数,所以错误也有可能是整数,也验证了点2 ,所以在协议栈的上一层使用这个函数的时候,可能需要注意error的处理部分

4. 不管这个函数返回什么值,这个skb最终的宿命就是被consume,也就是free掉了... 所以这个时候上层不要尝试重发了... 除非有协议栈的重传, 要不skb已经被free了,再去重新去调用,不要命了..此时kernel就挂掉了...

5.在调用这个函数的时候,必须打开中断,这些东西不是特别明白原因....
zs_2016 2016-08-25
  • 打赏
  • 举报
回复
没搞过这个,检索了一下dev_queue_xmit,找到一篇文章,感觉对你有用http://www.mobile-open.com/2016/974079.html

1,323

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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