/*** * 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; }
/*** * 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; }