示例#1
0
文件: route.c 项目: hiddeate2m/rtnet
/***
 *  rt_ip_route_add_host: add or update host route
 */
int rt_ip_route_add_host(u32 addr, unsigned char *dev_addr,
                         struct rtnet_device *rtdev)
{
    rtdm_lockctx_t      context;
    struct host_route   *new_route;
    struct host_route   *rt;
    unsigned int        key;
    int                 ret = 0;


    rtdm_lock_get_irqsave(&rtdev->rtdev_lock, context);

    if ((!test_bit(PRIV_FLAG_UP, &rtdev->priv_flags) ||
        test_and_set_bit(PRIV_FLAG_ADDING_ROUTE, &rtdev->priv_flags))) {
        rtdm_lock_put_irqrestore(&rtdev->rtdev_lock, context);
        return -EBUSY;
    }

    rtdm_lock_put_irqrestore(&rtdev->rtdev_lock, context);

    if ((new_route = rt_alloc_host_route()) != NULL) {
        new_route->dest_host.ip    = addr;
        new_route->dest_host.rtdev = rtdev;
        memcpy(new_route->dest_host.dev_addr, dev_addr, rtdev->addr_len);
    }

    key = ntohl(addr) & HOST_HASH_KEY_MASK;

    rtdm_lock_get_irqsave(&host_table_lock, context);

    rt = host_hash_tbl[key];
    while (rt != NULL) {
        if ((rt->dest_host.ip == addr) &&
            (rt->dest_host.rtdev->local_ip == rtdev->local_ip)) {
            rt->dest_host.rtdev = rtdev;
            memcpy(rt->dest_host.dev_addr, dev_addr, rtdev->addr_len);

            if (new_route)
                rt_free_host_route(new_route);

            rtdm_lock_put_irqrestore(&host_table_lock, context);

            goto out;
        }

        rt = rt->next;
    }

    if (new_route) {
        new_route->next    = host_hash_tbl[key];
        host_hash_tbl[key] = new_route;

        rtdm_lock_put_irqrestore(&host_table_lock, context);
    } else {
        rtdm_lock_put_irqrestore(&host_table_lock, context);

        /*ERRMSG*/rtdm_printk("RTnet: no more host routes available\n");
        ret = -ENOBUFS;
    }

  out:
    clear_bit(PRIV_FLAG_ADDING_ROUTE, &rtdev->priv_flags);

    return ret;
}
示例#2
0
/***
 *  rt_ip_route_add_host: add or update host route
 */
int rt_ip_route_add_host(u32 addr, unsigned char *dev_addr,
                         struct rtnet_device *rtdev)
{
    unsigned long       flags;
    struct host_route   *new_route;
    struct host_route   *rt;
    unsigned int        key;


    rtos_spin_lock_irqsave(&rtdev->rtdev_lock, flags);

    if ((!test_bit(PRIV_FLAG_UP, &rtdev->priv_flags) ||
        test_and_set_bit(PRIV_FLAG_ADDING_ROUTE, &rtdev->priv_flags))) {
        rtos_spin_unlock_irqrestore(&rtdev->rtdev_lock, flags);
        return -EBUSY;
    }

    rtos_spin_unlock_irqrestore(&rtdev->rtdev_lock, flags);

    if ((new_route = rt_alloc_host_route()) != NULL) {
        new_route->dest_host.ip    = addr;
        new_route->dest_host.rtdev = rtdev;
        memcpy(new_route->dest_host.dev_addr, dev_addr, rtdev->addr_len);
    }

    key = ntohl(addr) & HOST_HASH_KEY_MASK;

    rtos_spin_lock_irqsave(&host_table_lock, flags);

    rt = host_table[key];
    while (rt != NULL) {
        if (rt->dest_host.ip == addr) {
            rt->dest_host.rtdev = rtdev;
            memcpy(rt->dest_host.dev_addr, dev_addr, rtdev->addr_len);

            if (new_route)
                rt_free_host_route(new_route);

            rtos_spin_unlock_irqrestore(&host_table_lock, flags);

            goto out;
        }

        rt = rt->next;
    }

    if (new_route) {
        new_route->next = host_table[key];
        host_table[key] = new_route;

        rtos_spin_unlock_irqrestore(&host_table_lock, flags);
    } else {
        rtos_spin_unlock_irqrestore(&host_table_lock, flags);

        /*ERRMSG*/rtos_print("RTnet: no more host routes available\n");
    }

  out:
    clear_bit(PRIV_FLAG_ADDING_ROUTE, &rtdev->priv_flags);

    return 0;
}