九阳神功爱喝茶 发表于 2015-04-29 10:30

这是我一个毕业几年的师兄写的一个ip层的并发传输模块,没看懂怎么并发传输的?

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/netdevice.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/ip.h>

extern int ip_rcv_finish(struct sk_buff *skb);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("伍鹏飞");
MODULE_DESCRIPTION("多径路由并发模块");
MODULE_VERSION("0.0.1");

static unsigned char rule_ip = {192,168,1,0}; // target capture ip default parameter
static unsigned char rule_mask = {255,255,255,0};//MUSTget local host ip
static unsigned intmirule_ip;
static unsigned intmimask;
static unsigned intanum = 4;
       
module_param_array(rule_ip, byte,&anum, S_IRUSR|S_IWUSR);       
module_param_array(rule_mask, byte,&anum, S_IRUSR|S_IWUSR);

unsigned int nf_hook_pre(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 *skb2;
        struct iphdr *iph = ip_hdr(skb);
        struct iphdr *iph2;
        mirule_ip = *(unsigned int *)rule_ip;
        mimask = *(unsigned int *)rule_mask;
        if((iph->saddr^mirule_ip) & mimask) //如果源地址不是同一子网的,直接进行后面的处理,不进行并发
                return NF_ACCEPT;
        else
        {
                skb2 = skb_clone(skb,GFP_ATOMIC);
                iph2 = ip_hdr(skb2);

                iph2->tos = 0x04;
                iph2->check = 0;
                iph2->check = ip_fast_csum((unsigned char*)iph2, iph2->ihl);

                ip_rcv_finish(skb2);

                iph->tos = 0x08;
                iph->check = 0;
                iph->check = ip_fast_csum((unsigned char*)iph, iph->ihl);
        }
        return NF_ACCEPT;
}

unsigned int nf_hook_in(unsigned int hooknum, struct sk_buff *skb,
                                const struct net_device *in,   
                                const struct net_device *out,                        
                                int (*okfn)(struct sk_buff *))
{
        struct iphdr *iph = ip_hdr(skb);
        if(iph->tos == 0x04)
                return NF_DROP;
        else
                return NF_ACCEPT;
}

static struct nf_hook_ops nf_pre =
{
        .hook = nf_hook_pre,
        .hooknum = NF_INET_PRE_ROUTING,
        .pf = PF_INET,
        .priority = NF_IP_PRI_FIRST,
};

static struct nf_hook_ops nf_in =
{
        .hook = nf_hook_in,
        .hooknum = NF_INET_LOCAL_IN,
        .pf = PF_INET,
        .priority = NF_IP_PRI_FIRST,
};       

static int __init init(void)
{
        nf_register_hook(&nf_pre);
        nf_register_hook(&nf_in);
    printk(KERN_ALERT "insmod mulpath successful!\n");
        return 0;
}

static void __exit exit(void)
{   
        nf_unregister_hook(&nf_pre);
        nf_unregister_hook(&nf_in);   
        printk(KERN_ALERT "rmmod mulpath successful!\n");
}

module_init(init);
module_exit(exit);

九阳神功爱喝茶 发表于 2015-04-29 10:31

钩子函数我理解,但是我很不理解这怎么成了多径并发的?

nswcfd 发表于 2015-04-29 11:07

跟基于tos的路由配合吧(策略路由ip route xxx)。
相当于一个报文,先按照tos=4路由一次,再按照tos=8路由一次。
并且tos=4的时候不希望本地接收。

由于只进行了skb_clone,data部分还是被原始skb和新的skb1共享的,如果skb被缓存在队列上(tc qdisc或者网卡的ring),
理论上对skb1的修改(比如tos/check/以及后续的dest mac)还是有可能体现到原始skb上的。

九阳神功爱喝茶 发表于 2015-04-29 11:56

谢谢,我刚分析的也是这个差不多的意思。但是我很不理解这个地方

比如当数据包第一次被拦截进入nf_hook_pre函数之后,如果TOS=4,那么数据包被路由或者被本地接收,当然在被本地接受后悔在nf_hook_in中丢掉数据包;也就是数据包在TOS=4的时候要么会被丢弃,要么会被路由出去;
而在TOS=8的时候要么被接收,要么被路由出去。
是这样的吗?
如果TOS=4的时候被路由出去,TOS=8时候被接收,这我还能理解是多径传输,其他的情况都不是吧、

回复 3# nswcfd


   

nswcfd 发表于 2015-04-29 14:36

不一定非得“本地 + 转发”才叫多路,“转发1 + 转发2”也可以吧。
只要命中不同的路由(比如选择不同的出口,或者使用不同的下一跳)不就是multi path了么,
虽然它们在netfilter下的code path都是一样的……(严格说来也有区别)

至于“多径”传输的本义和既定应用场景,估计还得找作者本人问问。

九阳神功爱喝茶 发表于 2015-04-29 15:32

好,我已经在给这位师兄发邮件了。谢谢你回复 5# nswcfd


   

xlhl3 发表于 2015-05-26 21:51

回复 1# 九阳神功爱喝茶
你好, 我想问下你问的结果是什么呀?
我的理解是:
如果数据包的tos == 4 且目的地址是本地的话,该数据包则丢弃;
如果数据包的tos == 4 且目的地址不是本地的话,则该数据包转发;
如果数据包的tos == 8 则该数据包要么被接受,要么被转发

如果TOS == 4的时候被路由出去,TOS == 8时候被接收的情况不会发生吧?
因为在 TOS==4 和 TOS == 8 的时候,目的地址是确定的呀?除非在tos == 8 的时候改变目的地址为本机,这样才会发生吧,但是在代码中没有对目的地址做更改呀? 所以我认为不会发生(除非在其他地方做了处理)。

   

nswcfd 发表于 2015-05-27 16:52

揣测作者的原意,在代码之外,在命令行配置层面,至少有两条基于tos的策略路由(ip rule + ip route)。

路由不改变目的IP,只是选择不同的出口或下一跳(体现在对目的MAC的改变上,ARP子系统)

xlhl3 发表于 2015-05-29 18:08

回复 8# nswcfd

嗯 嗯,很有可能是这样做的!{:qq8:}


   

九阳神功爱喝茶 发表于 2015-06-07 20:55

厉害,我仔细看了下他的论文,确是是这个意思。不过他这样设计我觉得有个问题:接收方最后还是只能收到TOS=8的这条路来的数据包,所以并不是传统意义上只要有一个OK就可以了的。nswcfd 发表于 2015-05-27 16:52 static/image/common/back.gif
揣测作者的原意,在代码之外,在命令行配置层面,至少有两条基于tos的策略路由(ip rule + ip route)。

...
页: [1]
查看完整版本: 这是我一个毕业几年的师兄写的一个ip层的并发传输模块,没看懂怎么并发传输的?