ip_route_input() -- IP路由(输入路由)

190 篇文章 1 订阅
ip_rcv_finish() --> ip_route_input()

    ip_route_input()给进来的包skb查找路由,现在缓冲区的路由hash表中查找,如果没找到,在调用ip_route_input_slow()到路由表中查找。

    The function ip_route_input() is invoked for each IP packet arriving over a network interface. The parameters are a pointer to the socket-buffer structure, the destination and source addresses, the TOS value, and a pointer to the net_device structure of the receiving network interface.

    First, rt_hash() is used on the addresses and the TOS value to compute an index in the hash table of the routing cache. If necessary, the list anchored in the chain element is walked through to find a cache entry matching addresses, input interface, TOS value, and fwmark, if present. If this search is successful, then a pointer to the entry is placed as dst in the sk_buff structure, and the task is complete. 

    If no matching cache entry is found, then either of the two following functions is responsible for further handling: 
    ip_route_input_mc() is invoked if the destination address is a multicast address. Another prerequisite is that the input interface either belongs to that multicast group or has been configured for multicast routing. The packet can be discarded if this is not the case. What is done there is similar to the procedure for local-destination addresses described below, the only difference being that the packet is always delivered to the local machine rather than causing an FIB query.
    ip_route_input_slow() serves to handle "normal" destination addresses.


/usr/src/linux-2.6.19/net/ipv4/route.c

int  ip_route_input(struct  sk_buff *skb, __be32 daddr, __be32 saddr,
           u8 tos, struct  net_device *dev)
{
    struct  rtable * rth;
    unsigned    hash;
    int iif = dev->ifindex;
    tos &= IPTOS_RT_MASK;
    hash =  rt_hash(daddr, saddr, iif);
    rcu_read_lock();

    for (rth = rcu_dereference( rt_hash_table[hash].chain); rth;
         rth = rcu_dereference(rth->u.rt_next)) {
        if (rth->fl.fl4_dst == daddr &&
            rth->fl.fl4_src == saddr &&
            rth->fl.iif == iif &&
            rth->fl.oif == 0 &&
#ifdef CONFIG_IP_ROUTE_FWMARK
            rth->fl.fl4_fwmark == skb->nfmark &&
#endif
            rth->fl.fl4_tos == tos) {
            rth->u.dst.lastuse = jiffies;
            dst_hold(&rth->u.dst);
            rth->u.dst.__use++;
            RT_CACHE_STAT_INC(in_hit);
            rcu_read_unlock();
             skb->dst = (struct dst_entry*)rth;
            return 0;
        }
        RT_CACHE_STAT_INC(in_hlist_search);
    }

    rcu_read_unlock();
    if (MULTICAST(daddr)) {
        struct  in_device *in_dev;
        rcu_read_lock();
        if ((in_dev = __in_dev_get_rcu(dev)) != NULL) {
            int our = ip_check_mc(in_dev, daddr, saddr,
                skb->nh.iph->protocol);
            if (our
#ifdef CONFIG_IP_MROUTE
                || (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev))
#endif
                ) {
                rcu_read_unlock();
                return  ip_route_input_mc(skb, daddr, saddr,
                             tos, dev, our);
            }
        }
        rcu_read_unlock();
        return -EINVAL;
    }

    return  ip_route_input_slow(skb, daddr, saddr, tos, dev);
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值