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

Reply via email to