转:http://blog.csdn.net/nerdx/article/details/12911337
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1.1 int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
-
u8 tos, struct net_device *dev)
-
{
-
struct rtable * rth;
-
unsigned hash;
-
int iif = dev->ifindex;
-
-
tos &= IPTOS_RT_MASK;
-
hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos);
-
-
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 &&
-
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(dev)) != NULL) {
-
int our = ip_check_mc(in_dev, daddr, saddr,
-
skb->nh.iph->protocol);
-
-
if (our|| (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev)))
-
{
-
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);
-
}
-
-
-
-
-
-
-
-
-
-
-
-
2.1 int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr, u16 proto)
-
{
-
struct ip_mc_list *im;
-
struct ip_sf_list *psf;
-
int rv = 0;
-
-
read_lock(&in_dev->mc_list_lock);
-
-
for (im=in_dev->mc_list; im; im=im->next) {
-
if (im->multiaddr == mc_addr)
-
break;
-
}
-
-
if (im && proto == IPPROTO_IGMP) {
-
rv = 1;
-
} else if (im) {
-
-
if (src_addr) {
-
for (psf=im->sources; psf; psf=psf->sf_next) {
-
if (psf->sf_inaddr == src_addr)
-
break;
-
}
-
-
if (psf)
-
{
-
-
rv = psf->sf_count[MCAST_INCLUDE] ||
-
psf->sf_count[MCAST_EXCLUDE] !=
-
im->sfcount[MCAST_EXCLUDE];
-
}
-
else
-
{
-
-
rv = im->sfcount[MCAST_EXCLUDE] != 0;
-
}
-
-
} else
-
rv = 1;
-
}
-
read_unlock(&in_dev->mc_list_lock);
-
return rv;
-
}
-
-
-
-
-
-
-
-
-
3.1 static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
-
u8 tos, struct net_device *dev, int our)
-
{
-
unsigned hash;
-
struct rtable *rth;
-
u32 spec_dst;
-
struct in_device *in_dev = in_dev_get(dev);
-
u32 itag = 0;
-
-
-
rth = dst_alloc(&ipv4_dst_ops);
-
-
rth->u.dst.output = ip_rt_bug;
-
atomic_set(&rth->u.dst.__refcnt, 1);
-
rth->u.dst.flags= DST_HOST;
-
if (in_dev->cnf.no_policy)
-
rth->u.dst.flags |= DST_NOPOLICY;
-
-
rth->u.dst.dev = &loopback_dev;
-
dev_hold(rth->u.dst.dev);
-
-
-
rth->fl.fl4_dst = daddr;
-
rth->fl.fl4_tos = tos;
-
rth->fl.fl4_src = saddr;
-
rth->fl.iif = dev->ifindex;
-
rth->fl.oif = 0;
-
-
-
-
rth->rt_dst = daddr;
-
rth->rt_src = saddr;
-
rth->rt_iif = dev->ifindex;
-
rth->rt_gateway = daddr;
-
rth->rt_spec_dst= spec_dst;
-
rth->rt_type = RTN_MULTICAST;
-
rth->rt_flags = RTCF_MULTICAST;
-
rth->idev = in_dev_get(rth->u.dst.dev);
-
-
-
if (our) {
-
rth->u.dst.input= ip_local_deliver;
-
rth->rt_flags |= RTCF_LOCAL;
-
}
-
-
-
#ifdef CONFIG_IP_MROUTE
-
-
-
if (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev))
-
rth->u.dst.input = ip_mr_input;
-
#endif
-
-
in_dev_put(in_dev);
-
hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos);
-
-
return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
-
-
}
阅读(1132) | 评论(0) | 转发(0) |