This patch adds te IOCTL request IOC_RT_HOST_ROUTE_RESOLVED to check if an IPv4 host address has been resolved. A timeout can be specified to await the address resolution (ARP reply). The rtroute utility supports this request and serves as example:
# rtroute solicit <addr> dev <dev> [wait <ms>] Signed-off-by: Wolfang Grandegger <[EMAIL PROTECTED]> Index: rtnet/stack/include/ipv4/route.h =================================================================== --- rtnet.orig/stack/include/ipv4/route.h +++ rtnet/stack/include/ipv4/route.h @@ -53,6 +53,7 @@ int rt_ip_route_forward(struct rtskb *rt #ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC int __rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev); +int __rt_ip_route_host_resolved(u32 addr, struct rtnet_device *rtdev); int __rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr); static inline int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev) @@ -60,6 +61,12 @@ static inline int rt_ip_route_del_host(u return __rt_ip_route_del_host(addr, rtdev); } +static inline int rt_ip_route_host_resolved(u32 addr, + struct rtnet_device *rtdev) +{ + return __rt_ip_route_host_resolved(addr, rtdev); +} + static inline int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr) { @@ -67,6 +74,7 @@ static inline int rt_ip_route_output(str } #else /* !CONFIG_RTNET_RTIPV4_ROUTE_SRC */ int __rt_ip_route_del_host(u32 addr); +int __rt_ip_route_host_resolved(u32 addr); int __rt_ip_route_output(struct dest_route *rt_buf, u32 daddr); static inline int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev) @@ -74,6 +82,12 @@ static inline int rt_ip_route_del_host(u return __rt_ip_route_del_host(addr); } +static inline int rt_ip_route_host_resolved(u32 addr, + struct rtnet_device *rtdev) +{ + return __rt_ip_route_host_resolved(addr); +} + static inline int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr) { Index: rtnet/stack/include/ipv4_chrdev.h =================================================================== --- rtnet.orig/stack/include/ipv4_chrdev.h +++ rtnet/stack/include/ipv4_chrdev.h @@ -39,6 +39,11 @@ struct ipv4_cmd { struct { __u32 ip_addr; + int timeout; + } resolved; + + struct { + __u32 ip_addr; unsigned char dev_addr[DEV_ADDR_LEN]; } addhost; @@ -86,7 +91,10 @@ struct ipv4_cmd { #define IOC_RT_PING _IOWR(RTNET_IOC_TYPE_IPV4, 5 | \ RTNET_IOC_NODEV_PARAM, \ struct ipv4_cmd) -#define IOC_RT_HOST_ROUTE_DELETE_DEV _IOW(RTNET_IOC_TYPE_IPV4, 6, \ +#define IOC_RT_HOST_ROUTE_DELETE_DEV _IOW(RTNET_IOC_TYPE_IPV4, 6, \ struct ipv4_cmd) +#define IOC_RT_HOST_ROUTE_RESOLVED _IOW(RTNET_IOC_TYPE_IPV4, 7 | \ + RTNET_IOC_NODEV_PARAM, \ + struct ipv4_cmd) #endif /* __IPV4_H_ */ Index: rtnet/stack/ipv4/af_inet.c =================================================================== --- rtnet.orig/stack/ipv4/af_inet.c +++ rtnet/stack/ipv4/af_inet.c @@ -123,6 +123,7 @@ static int ipv4_ioctl(struct rtnet_devic struct ipv4_cmd cmd; struct route_solicit_params params; int ret; + int timeout; ret = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); @@ -162,6 +163,17 @@ static int ipv4_ioctl(struct rtnet_devic ret = rt_ip_route_del_host(cmd.args.delhost.ip_addr, rtdev); break; + case IOC_RT_HOST_ROUTE_RESOLVED: + timeout = jiffies + (cmd.args.resolved.timeout * HZ / 1000); + while (1) { + ret = rt_ip_route_host_resolved(cmd.args.resolved.ip_addr, + rtdev); + if (!ret || jiffies >= timeout) + break; + schedule_timeout(1); + } + break; + #ifdef CONFIG_RTNET_RTIPV4_NETROUTING case IOC_RT_NET_ROUTE_ADD: ret = rt_ip_route_add_net(cmd.args.addnet.net_addr, Index: rtnet/stack/ipv4/route.c =================================================================== --- rtnet.orig/stack/ipv4/route.c +++ rtnet/stack/ipv4/route.c @@ -509,6 +509,47 @@ void rt_ip_route_del_all(struct rtnet_de } +/*** + * rt_ip_route_host_resolved - check if specified host route is resolved + */ +int __rt_ip_route_host_resolved(u32 addr +#ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC + , struct rtnet_device *rtdev +#endif /* CONFIG_RTNET_RTIPV4_ROUTE_SRC */ + ) +{ + rtdm_lockctx_t context; + struct host_route *rt; + struct host_route **last_ptr; + unsigned int key; + + + key = ntohl(addr) & HOST_HASH_KEY_MASK; + last_ptr = &host_hash_tbl[key]; + + rtdm_lock_get_irqsave(&host_table_lock, context); + + rt = host_hash_tbl[key]; + while (rt != NULL) { + if ((rt->dest_host.ip == addr) +#ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC + && (!rtdev_src || + (rt->dest_host.rtdev->local_ip == rtdev_src->local_ip)) +#endif + ) { + rtdm_lock_put_irqrestore(&host_table_lock, context); + return 0; + } + + last_ptr = &rt->next; + rt = rt->next; + } + + rtdm_lock_put_irqrestore(&host_table_lock, context); + + return -ENOENT; +} + #ifdef CONFIG_RTNET_RTIPV4_NETROUTING /*** Index: rtnet/tools/rtroute.c =================================================================== --- rtnet.orig/tools/rtroute.c +++ rtnet/tools/rtroute.c @@ -49,7 +49,7 @@ void help(void) { fprintf(stderr, "Usage:\n" "\trtroute\n" - "\trtroute solicit <addr> dev <dev>\n" + "\trtroute solicit <addr> dev <dev> [wait <ms>]\n" "\trtroute add <addr> <hwaddr> dev <dev>\n" "\trtroute add <addr> netmask <mask> gw <gw-addr>\n" "\trtroute del <addr> [dev <dev>]\n" @@ -107,7 +107,7 @@ void route_solicit(int argc, char *argv[ int ret; - if ((argc != 5) || (strcmp(argv[3], "dev") != 0)) + if ((argc < 5) || (strcmp(argv[3], "dev") != 0)) help(); strncpy(cmd.head.if_name, argv[4], IFNAMSIZ); @@ -118,6 +118,24 @@ void route_solicit(int argc, char *argv[ perror("ioctl"); exit(1); } + + if ((argc == 7) && strcmp(argv[5], "wait") == 0) { + /* wait for completion */ + cmd.args.resolved.ip_addr = addr.s_addr; + cmd.args.resolved.timeout = atoi(argv[6]); + ret = ioctl(f, IOC_RT_HOST_ROUTE_RESOLVED, &cmd); + if (ret < 0) { + if (errno == ENOENT) { + fprintf(stderr, "Address %s is not resolved after %d ms\n", + argv[2], cmd.args.resolved.timeout); + } else { + perror("ioctl"); + } + exit(1); + } + printf("Address %s now resolved\n", argv[2]); + } + exit(0); } -- ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ RTnet-users mailing list RTnet-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rtnet-users