示例#1
0
static void rt_redirect_1(__u32 dst, __u32 gw, struct device *dev)
{
	struct rtable *rt;
	unsigned long hash = ip_rt_hash_code(dst);

	if (gw == dev->pa_addr)
		return;
	if (dev != get_gw_dev(gw))
		return;
	rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
	if (rt == NULL) 
		return;
	memset(rt, 0, sizeof(struct rtable));
	rt->rt_flags = RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY | RTF_UP;
	rt->rt_dst = dst;
	rt->rt_dev = dev;
	rt->rt_gateway = gw;
	rt->rt_src = dev->pa_addr;
	rt->rt_mtu = dev->mtu;
#ifdef CONFIG_NO_PATH_MTU_DISCOVERY
	if (dev->mtu > 576)
		rt->rt_mtu = 576;
#endif
	rt->rt_lastuse  = jiffies;
	rt->rt_refcnt  = 1;
	rt_cache_add(hash, rt);
	ip_rt_put(rt);
	return;
}
示例#2
0
void ip_rt_add(short flags, unsigned long dst, unsigned long mask, unsigned long gw, struct net_device *dev, \
        unsigned short mtu, unsigned long window)
{
    struct rtable *rt,*r,*prev;
    struct rtable **rtp; 

    unsigned long rtflags;
    // is dst is host address
    if(flags & RTF_HOST)
        mask = 0xffffffff;

    // network address
    else if(!mask)
    {
        //	if(!((dst ^ dev->pa_mask) ^ dev->pa_addr))
        if(!((dst ^ dev->pa_addr ) & dev->pa_mask ))
        {
            mask = dev->pa_mask;
            flags &= ~RTF_GATEWAY;
        }
        else 
            mask = guess_mask(dst,dev);
        dst &= mask;
    }

    if(gw == dev->pa_addr)
    {
        flags &= ~RTF_GATEWAY;
    }

    if(flags & RTF_GATEWAY)
    {
        if(dev != get_gw_dev(gw))
            return;
        flags |= RTF_GATEWAY;
    }
    else
        gw = 0;

    //		rt = (struct rtable *)kmalloc(sizeof(struct rtable),GFP_ATOMIC);
    if(rt == NULL)
        return;
    memset((char *)rt, 0, sizeof(struct rtable));
    rt->rt_flags = flags | RTF_UP;
    rt->rt_dst = dst;
    rt->rt_dev = dev;
    rt->rt_gateway = gw;
    rt->rt_mask = mask;
    //		rt->rt_mss = dev->mtu - HEADER_SIZE;
    rt->rt_window = 0;

    if(rt->rt_flags & RTF_MSS)
        rt->rt_mss = mtu;
    if(rt->rt_flags & RTF_WINDOW)
        rt->rt_window = window;

    save_flags(rtflags);
    cli();

    rtp = &rt_base;
    while((r = *rtp) != NULL)
    {
        if((r->rt_dst != dst) || r->rt_mask != mask)
        {
            rtp = &r->rt_next;
        }
        else
            *rtp = r->rt_next;
        //			kfree_s(r,sizeof(struct rtable));
    }

    rtp = &rt_base;
    while((r = *rtp) != NULL)
    {
        if((r->rt_mask & mask) != mask)
            break;
        rtp = &r->rt_next;
        prev = r;
    }

    rt->rt_next = r;	
    prev->rt_next = rt;
    //		*rtp = rt;
    //		if((rt->rt_dev->flags & IFF_LOOPBACK) && !rt_loopback)
    //				rt_loopback = rt;
    restore_flags(rtflags);
    return;
}