netdev-tunnel's are now always listening
[sliver-openvswitch.git] / lib / netdev-tunnel.c
index 41b0fd5..d9c54c3 100644 (file)
@@ -47,14 +47,14 @@ struct netdev_dev_tunnel {
     int sockfd;
     struct sockaddr_in local_addr;
     struct sockaddr_in remote_addr;
-    bool got_remote_ip;
+    bool valid_remote_ip;
+    bool valid_remote_port;
     bool connected;
     unsigned int change_seq;
 };
 
 struct netdev_tunnel {
     struct netdev netdev;
-    bool listening;
 };
 
 static struct shash tunnel_netdev_devs = SHASH_INITIALIZER(&tunnel_netdev_devs);
@@ -104,7 +104,8 @@ netdev_tunnel_create(const struct netdev_class *class, const char *name,
     netdev_dev->flags = 0;
     netdev_dev->change_seq = 1;
     memset(&netdev_dev->remote_addr, 0, sizeof(netdev_dev->remote_addr));
-    netdev_dev->got_remote_ip = false;
+    netdev_dev->valid_remote_ip = false;
+    netdev_dev->valid_remote_port = false;
     netdev_dev->connected = false;
 
 
@@ -151,7 +152,6 @@ netdev_tunnel_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
 
     netdev = xmalloc(sizeof *netdev);
     netdev_init(&netdev->netdev, netdev_dev_);
-    netdev->listening = false;
 
     *netdevp = &netdev->netdev;
     return 0;
@@ -167,6 +167,14 @@ netdev_tunnel_close(struct netdev *netdev_)
 static int
 netdev_tunnel_get_config(struct netdev_dev *dev_, struct shash *args)
 {
+    struct netdev_dev_tunnel *netdev_dev = netdev_dev_tunnel_cast(dev_);
+
+    if (netdev_dev->valid_remote_ip)
+       shash_add(args, "remote_ip",
+           xasprintf(IP_FMT, IP_ARGS(&netdev_dev->remote_addr.sin_addr)));
+    if (netdev_dev->valid_remote_port)
+        shash_add(args, "remote_port",
+           xasprintf("%"PRIu16, ntohs(netdev_dev->remote_addr.sin_port)));
     return 0;
 }
 
@@ -175,7 +183,7 @@ netdev_tunnel_connect(struct netdev_dev_tunnel *dev)
 {
     if (dev->sockfd < 0)
         return EBADF;
-    if (!dev->got_remote_ip || !dev->remote_addr.sin_port)
+    if (!dev->valid_remote_ip || !dev->valid_remote_port)
         return 0;
     dev->remote_addr.sin_family = AF_INET;
     if (connect(dev->sockfd, (struct sockaddr*) &dev->remote_addr, sizeof(dev->remote_addr)) < 0) {
@@ -192,31 +200,32 @@ netdev_tunnel_set_config(struct netdev_dev *dev_, const struct shash *args)
 {
     struct netdev_dev_tunnel *netdev_dev = netdev_dev_tunnel_cast(dev_);
     struct shash_node *node;
-    void *data;
 
     VLOG_DBG("tunnel_set_config(%s)", netdev_dev_get_name(dev_));
     SHASH_FOR_EACH(node, args) {
-        VLOG_DBG("arg: %s->%s", node->name, node->data);
-    }
-    data = shash_find_data(args, "remote_ip");
-    if (data) {
-        struct in_addr addr;
-        int error = lookup_ip(data, &addr);
-        if (error)
-            return error;
-        netdev_dev->remote_addr.sin_addr = addr;
-        netdev_dev->got_remote_ip = true;
-        return netdev_tunnel_connect(netdev_dev);        
+        VLOG_DBG("arg: %s->%s", node->name, (char*)node->data);
+       if (!strcmp(node->name, "remote_ip")) {
+           struct in_addr addr;
+           if (lookup_ip(node->data, &addr)) {
+               VLOG_WARN("%s: bad 'remote_ip'", node->name);
+           } else {
+               netdev_dev->remote_addr.sin_addr = addr;
+               netdev_dev->valid_remote_ip = true;
+           }
+       } else if (!strcmp(node->name, "remote_port")) {
+           netdev_dev->remote_addr.sin_port = htons(atoi(node->data));
+           netdev_dev->valid_remote_port = true;
+       } else {
+           VLOG_WARN("%s: unknown argument '%s'", 
+               netdev_dev_get_name(dev_), node->name);
+       }
     }
-    return 0;
+    return netdev_tunnel_connect(netdev_dev);        
 }
 
 static int
 netdev_tunnel_listen(struct netdev *netdev_)
 {
-    struct netdev_tunnel *netdev = netdev_tunnel_cast(netdev_);
-    VLOG_DBG("tunnel_listen(%s)", netdev_get_name(netdev_));
-    netdev->listening = true;
     return 0;
 }
 
@@ -411,9 +420,6 @@ netdev_tunnel_poll_notify(const struct netdev *netdev)
     }
 }
 
-#define LPORT ((void*)1)
-#define RPORT ((void*)2)
-
 static void
 netdev_tunnel_get_port(struct unixctl_conn *conn,
                      int argc, const char *argv[], void *aux OVS_UNUSED)
@@ -428,45 +434,16 @@ netdev_tunnel_get_port(struct unixctl_conn *conn,
         return;
     }
 
-    port = (aux == LPORT ? tunnel_dev->local_addr.sin_port
-                        : tunnel_dev->remote_addr.sin_port);
-    
-    sprintf(buf, "%d", ntohs(port));
+    sprintf(buf, "%d", ntohs(tunnel_dev->local_addr.sin_port));
     unixctl_command_reply(conn, buf);
 }
 
-static void
-netdev_tunnel_set_rport(struct unixctl_conn *conn,
-                     int argc, const char *argv[], void *aux OVS_UNUSED)
-{
-    struct netdev_dev_tunnel *tunnel_dev;
-    int error;
-
-    tunnel_dev = shash_find_data(&tunnel_netdev_devs, argv[1]);
-    if (!tunnel_dev) {
-        unixctl_command_reply_error(conn, "no such tunnel netdev");
-        return;
-    }
-
-    tunnel_dev->remote_addr.sin_port = htons(atoi(argv[2]));
-
-    error = netdev_tunnel_connect(tunnel_dev);
-    if (error) {
-        unixctl_command_reply_error(conn, strerror(errno));
-    } else {
-        unixctl_command_reply(conn, "ok");
-    }
-}
 
 static int
 netdev_tunnel_init(void)
 {
-    unixctl_command_register("netdev-tunnel/get-lport", "NAME",
-                             1, 1, netdev_tunnel_get_port, LPORT);
-    unixctl_command_register("netdev-tunnel/get-rport", "NAME",
-                             1, 1, netdev_tunnel_get_port, RPORT);
-    unixctl_command_register("netdev-tunnel/set-rport", "NAME PORT",
-                             2, 2, netdev_tunnel_set_rport, 0);
+    unixctl_command_register("netdev-tunnel/get-port", "NAME",
+                             1, 1, netdev_tunnel_get_port, NULL);
     return 0;
 }