免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2972 | 回复: 6
打印 上一主题 下一主题

[内核模块] 调用函数 dev_queue_xmit 问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-12 10:05 |只看该作者 |倒序浏览
本帖最后由 mengxh3000 于 2014-08-12 10:17 编辑

在网桥的 NF_BR_POST_ROUTING 里面 把普通的ETH_P_IP包添加vlan id 变成ETH_P_8021Q的包,调用 dev_queue_xmit 返回0,但是对方并没有收到包。(本机没有配置vlan的虚拟网卡,就是用eth0发送)不知道问题出在哪里 ,代码如下:


static unsigned int brTestHookLocalPostRouting(unsigned int hooknum,
                                        struct sk_buff **skb,
                                        const struct net_device *in,
                                        const struct net_device *out,
                                        int (*okfn)(struct sk_buff *))
{
        int ret = 0;
        struct vlan_ethhdr *veth;
        struct sk_buff *pskb = *skb;

        if (pskb == NULL)
                return NF_DROP;

        //printk("PostRouting ---- \n");

        if (pskb->protocol == __constant_htons(ETH_P_8021Q))
        {
                return NF_ACCEPT;
        }
       
        hexDump(pskb->mac.raw, 60);
        printk("PostRouting ---- PostRouting\n");

             // 本机的mac地址,若是从本机发出的包就打上vlan id 为100的tag
        // 00 e9 24 13 12 49
        unsigned char* p = pskb->mac.raw;
        if (p[6] ==  0x00 && p[7] ==  0xe9 &&
                p[8] ==  0x24 && p[9] ==  0x13 &&
                p[10] == 0x12 && p[11] == 0x49)
        {
                printk("PostRouting ---- put tag\n");

                skb_push(pskb, ETH_HLEN);
                struct vlan_ethhdr *veth1;
                if (skb_headroom(pskb) < VLAN_HLEN)
                {
                        struct sk_buff *sk_tmp = pskb;
                        pskb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
                        kfree_skb(sk_tmp);
                        if (!pskb)
                        {
                                printk("PostRouting ---- vlan: failed to realloc headroom\n");
                                return NF_DROP;
                        }

                        //hexDump(pskb->mac.raw, 60);
                        //printk("PostRouting ---- skb_realloc_headroom \n");
                }
                else
                {
                        pskb = skb_unshare(pskb, GFP_ATOMIC);
                        if (!pskb)
                        {
                                printk("PostRouting ---- vlan: failed to unshare skbuff\n");
                                return NF_DROP;
                        }

                        //hexDump(pskb->mac.raw, 60);
                        //printk("PostRouting ---- skb_unshare \n");
                }

                veth1 = (struct vlan_ethhdr *)skb_push(pskb, VLAN_HLEN);

                //hexDump(pskb->mac.raw, 60);
                //printk("PostRouting ---- skb_push \n");

                /* Move the mac addresses to the beginning of the new header. */
                memmove(pskb->data, pskb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);

                //hexDump(pskb->mac.raw, 60);
                //printk("PostRouting ---- memmove \n");

                veth1->h_vlan_proto = __constant_htons(ETH_P_8021Q);
                veth1->h_vlan_TCI = htons(100);

                pskb->protocol = __constant_htons(ETH_P_8021Q);
                pskb->mac.raw -= VLAN_HLEN;
                pskb->nh.raw -= VLAN_HLEN;

                pskb->ip_summed = CHECKSUM_HW;

                hexDump(pskb->mac.raw, 60);

                //pskb = __vlan_put_tag(pskb, 10);
                printk("PostRouting ---- __vlan_put_tag \n");
                if (!pskb)
                {
                        printk("PostRouting ---- __vlan_put_tag failed \n");
                        //stats->tx_dropped++;
                        return NF_DROP;
                }

                printk("PostRouting----- pskb->dev->name = %s\n", pskb->dev->name);
                int rr = dev_queue_xmit(pskb);
                printk("PostRouting ---- dev_queue_xmit = %d\n", rr);
                return NF_STOLEN;
        }
        else
        {
                return NF_ACCEPT;
        }

        return NF_ACCEPT;
}

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-08-12 13:46 |只看该作者
对端做vlan相关配置了么?

论坛徽章:
0
3 [报告]
发表于 2014-08-12 14:11 |只看该作者
这台机器放在trunk链路上,通过本机的包都正常转发走了,就是本机发出的包打上vlan id

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
4 [报告]
发表于 2014-08-12 15:23 |只看该作者
楼主很执着的去改变标准的东西。你要非这么做,就你这个情况。可以在trunk链路上接个网络分析议(可以由电脑去左代替),看看发出来的包有什么不对,再有针对的去处理。

论坛徽章:
0
5 [报告]
发表于 2014-08-12 16:05 |只看该作者
因为这个放到trunk链路上因为有很多vlan,我用vconfig添加虚拟网卡,发现丢包严重,所以才想用这种方法。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2014-08-14 16:07 |只看该作者
抓包看看吧,发出去的报文格式内容对一下是否正确,然后再检查一下对端的配置是否正确,如果正确,看一下丢包计数之类的,先确认报文到哪里了,因为什么原因被丢弃了,一步一步有针对性的来就好了。

论坛徽章:
0
7 [报告]
发表于 2014-08-14 20:35 |只看该作者
1:在Postrouting并没有MAC头部,你这样处理,跳过ARP协议处理部分,肯定会不通。因为MAC头不对
2:你跳过了分片处理部分,超过MTU的包会出问题

还是用常规vconfig好,丢包严重与vconfig创建的虚拟接口没有关系,肯定是其它原因。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP