bridge: Move tunnel_egress_iface to status column.
authorEthan Jackson <ethan@nicira.com>
Wed, 5 Jan 2011 19:51:15 +0000 (11:51 -0800)
committerEthan Jackson <ethan@nicira.com>
Tue, 11 Jan 2011 20:33:44 +0000 (12:33 -0800)
This commit removes the tunnel_egress_iface column from the
interface table and moves it's data to the status column.  In the
process it reverts the database to version 1.0.0.

lib/netdev-dummy.c
lib/netdev-linux.c
lib/netdev-provider.h
lib/netdev-vport.c
lib/netdev.c
lib/netdev.h
vswitchd/bridge.c
vswitchd/vswitch.ovsschema
vswitchd/vswitch.xml

index 218a022..4569f97 100644 (file)
@@ -320,7 +320,7 @@ static const struct netdev_class dummy_class = {
     NULL,                       /* get_in6 */
     NULL,                       /* add_router */
     NULL,                       /* get_next_hop */
-    NULL,                       /* get_tnl_iface */
+    NULL,                       /* get_status */
     NULL,                       /* arp_lookup */
 
     netdev_dummy_update_flags,
index 5654dd4..97f9a64 100644 (file)
@@ -2176,7 +2176,7 @@ netdev_linux_poll_remove(struct netdev_notifier *notifier_)
     netdev_linux_get_in6,                                       \
     netdev_linux_add_router,                                    \
     netdev_linux_get_next_hop,                                  \
-    NULL,                       /* get_tnl_iface */             \
+    NULL,                       /* get_status */                \
     netdev_linux_arp_lookup,                                    \
                                                                 \
     netdev_linux_update_flags,                                  \
index 038f277..da0ad45 100644 (file)
@@ -518,16 +518,19 @@ struct netdev_class {
     int (*get_next_hop)(const struct in_addr *host, struct in_addr *next_hop,
                         char **netdev_name);
 
-    /* Looks up the name of the interface out of which traffic will egress if
-     * 'netdev' is a tunnel.  If unsuccessful, or 'netdev' is not a tunnel,
-     * will return null.  This function does not necessarily return the
-     * physical interface out which traffic will egress.  Instead it returns
-     * the interface which is assigned 'netdev's remote_ip.  This may be an
-     * internal interface such as a bridge port.
-     *
-     * This function may be set to null if 'netdev' is not a tunnel or it is
-     * not supported. */
-    const char *(*get_tnl_iface)(const struct netdev *netdev);
+    /* Retrieves the status of the device.
+     *
+     * Populates 'sh' with key-value pairs representing the status of the
+     * device.  A device's status is a set of key-value string pairs
+     * representing netdev type specific information.  For more information see
+     * ovs-vswitchd.conf.db(5).
+     *
+     * The data of 'sh' are heap allocated strings which the caller is
+     * responsible for deallocating.
+     *
+     * This function may be set to null if it would always return EOPNOTSUPP
+     * anyhow. */
+    int (*get_status)(const struct netdev *netdev, struct shash *sh);
 
     /* Looks up the ARP table entry for 'ip' on 'netdev' and stores the
      * corresponding MAC address in 'mac'.  A return value of ENXIO, in
index f3985e9..cf717cc 100644 (file)
@@ -100,6 +100,7 @@ static void netdev_vport_route_change(const struct rtnetlink_route_change *,
                                       void *);
 static void netdev_vport_link_change(const struct rtnetlink_link_change *,
                                      void *);
+static const char *netdev_vport_get_tnl_iface(const struct netdev *netdev);
 
 static bool
 is_vport_class(const struct netdev_class *class)
@@ -364,6 +365,18 @@ netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
     return err;
 }
 
+static int
+netdev_vport_get_status(const struct netdev *netdev, struct shash *sh)
+{
+    const char *iface = netdev_vport_get_tnl_iface(netdev);
+
+    if (iface) {
+        shash_add(sh, "tunnel_egress_iface", xstrdup(iface));
+    }
+
+    return 0;
+}
+
 static int
 netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED,
                         enum netdev_flags off, enum netdev_flags on OVS_UNUSED,
@@ -924,7 +937,7 @@ parse_patch_config(const struct netdev_dev *dev, const struct shash *args,
     return 0;
 }
 \f
-#define VPORT_FUNCTIONS(TNL_IFACE)                          \
+#define VPORT_FUNCTIONS(GET_STATUS)                         \
     netdev_vport_init,                                      \
     netdev_vport_run,                                       \
     netdev_vport_wait,                                      \
@@ -974,7 +987,7 @@ parse_patch_config(const struct netdev_dev *dev, const struct shash *args,
     NULL,                       /* get_in6 */               \
     NULL,                       /* add_router */            \
     NULL,                       /* get_next_hop */          \
-    TNL_IFACE,                                              \
+    GET_STATUS,                                             \
     NULL,                       /* arp_lookup */            \
                                                             \
     netdev_vport_update_flags,                              \
@@ -986,11 +999,11 @@ void
 netdev_vport_register(void)
 {
     static const struct vport_class vport_classes[] = {
-        { { "gre", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) },
+        { { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
             parse_tunnel_config },
-        { { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) },
+        { { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
             parse_tunnel_config },
-        { { "capwap", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) },
+        { { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
             parse_tunnel_config },
         { { "patch", VPORT_FUNCTIONS(NULL) }, parse_patch_config }
     };
index 4b2e59e..0f22327 100644 (file)
@@ -769,14 +769,19 @@ netdev_get_next_hop(const struct netdev *netdev,
     return error;
 }
 
-const char *
-netdev_get_tnl_iface(const struct netdev *netdev)
+/* Populates 'sh' with status information.
+ *
+ * Populates 'sh' with 'netdev' specific status information.  This information
+ * may be used to populate the status column of the Interface table as defined
+ * in ovs-vswitchd.conf.db(5). */
+int
+netdev_get_status(const struct netdev *netdev, struct shash *sh)
 {
     struct netdev_dev *dev = netdev_get_dev(netdev);
 
-    return (dev->netdev_class->get_tnl_iface
-            ? dev->netdev_class->get_tnl_iface(netdev)
-            : NULL);
+    return (dev->netdev_class->get_status
+            ? dev->netdev_class->get_status(netdev, sh)
+            : EOPNOTSUPP);
 }
 
 /* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address and
index d7d7097..50ad5a3 100644 (file)
@@ -141,7 +141,7 @@ int netdev_get_in6(const struct netdev *, struct in6_addr *);
 int netdev_add_router(struct netdev *, struct in_addr router);
 int netdev_get_next_hop(const struct netdev *, const struct in_addr *host,
                         struct in_addr *next_hop, char **);
-const char *netdev_get_tnl_iface(const struct netdev *);
+int netdev_get_status(const struct netdev *, struct shash *sh);
 int netdev_arp_lookup(const struct netdev *, uint32_t ip, uint8_t mac[6]);
 
 int netdev_get_flags(const struct netdev *, enum netdev_flags *);
index 8b07b3e..20cbee5 100644 (file)
@@ -288,6 +288,9 @@ static void iface_send_packet(struct iface *, struct ofpbuf *packet);
 
 static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
                                    struct shash *);
+static void shash_to_ovs_idl_map(struct shash *,
+                                 char ***keys, char ***values, size_t *n);
+
 
 /* Hooks into ofproto processing. */
 static struct ofhooks bridge_ofhooks;
@@ -1110,11 +1113,26 @@ dpid_from_hash(const void *data, size_t n)
 }
 
 static void
-iface_refresh_tunnel_egress(struct iface *iface)
+iface_refresh_status(struct iface *iface)
 {
-    const char *name = netdev_get_tnl_iface(iface->netdev);
+    struct shash sh;
+
+    shash_init(&sh);
+
+    if (!netdev_get_status(iface->netdev, &sh)) {
+        size_t n;
+        char **keys, **values;
 
-    ovsrec_interface_set_tunnel_egress_iface(iface->cfg, name);
+        shash_to_ovs_idl_map(&sh, &keys, &values, &n);
+        ovsrec_interface_set_status(iface->cfg, keys, values, n);
+
+        free(keys);
+        free(values);
+    } else {
+        ovsrec_interface_set_status(iface->cfg, NULL, NULL, 0);
+    }
+
+    shash_destroy_free_data(&sh);
 }
 
 static void
@@ -1326,7 +1344,7 @@ bridge_run(void)
                         struct iface *iface = port->ifaces[j];
                         iface_refresh_stats(iface);
                         iface_refresh_cfm_stats(iface);
-                        iface_refresh_tunnel_egress(iface);
+                        iface_refresh_status(iface);
                     }
                 }
             }
@@ -4152,6 +4170,38 @@ shash_from_ovs_idl_map(char **keys, char **values, size_t n,
     }
 }
 
+/* Creates 'keys' and 'values' arrays from 'shash'.
+ *
+ * Sets 'keys' and 'values' to heap allocated arrays representing the key-value
+ * pairs in 'shash'.  The caller takes ownership of 'keys' and 'values'.  They
+ * are populated with with strings taken directly from 'shash' and thus have
+ * the same ownership of the key-value pairs in shash.
+ */
+static void
+shash_to_ovs_idl_map(struct shash *shash,
+                     char ***keys, char ***values, size_t *n)
+{
+    size_t i, count;
+    char **k, **v;
+    struct shash_node *sn;
+
+    count = shash_count(shash);
+
+    k = xmalloc(count * sizeof *k);
+    v = xmalloc(count * sizeof *v);
+
+    i = 0;
+    SHASH_FOR_EACH(sn, shash) {
+        k[i] = sn->name;
+        v[i] = sn->data;
+        i++;
+    }
+
+    *n      = count;
+    *keys   = k;
+    *values = v;
+}
+
 struct iface_delete_queues_cbdata {
     struct netdev *netdev;
     const struct ovsdb_datum *queues;
index a8140b8..f975851 100644 (file)
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
- "version": "1.0.2",
- "cksum": "3196651018 14282",
+ "version": "1.0.3",
+ "cksum": "2654345387 14137",
  "tables": {
    "Open_vSwitch": {
      "columns": {
        "ingress_policing_burst": {
          "type": {"key": {"type": "integer",
                           "minInteger": 0}}},
-       "tunnel_egress_iface": {
-         "type": {"key": {"type": "string"},
-                  "min": 0, "max": 1},
-         "ephemeral": true},
        "mac": {
          "type": {"key": {"type": "string"},
                   "min": 0, "max": 1}},
index 7a70909..5a3abb0 100644 (file)
           Key-value pairs that report port status.  Supported status
           values are <code>type</code>-dependent.
         </p>
-        <p>The only currently defined key-value pair is:</p>
+        <p>The currently defined key-value pairs are:</p>
         <dl>
           <dt><code>source_ip</code></dt>
           <dd>The source IP address used for an IPv4 tunnel end-point,
             such as <code>gre</code> or <code>capwap</code>.  Not
             supported by all implementations.</dd>
         </dl>
+        <dl>
+            <dt><code>tunnel_egress_iface</code></dt>
+            <dd>Egress interface for tunnels.  Currently only relevant for GRE
+                and CAPWAP tunnels.  On Linux systems, this column will show
+                the name of the interface which is responsible for routing
+                traffic destined for the configured <code>remote_ip</code>.
+                This could be an internal interface such as a bridge port.</dd>
+        </dl>
       </column>
     </group>
 
         </dl>
       </column>
 
-      <column name="tunnel_egress_iface">
-        Egress interface for tunnels.  Currently only relevant for GRE and
-        CAPWAP tunnels.  On Linux systems, this column will show the name of
-        the interface which is responsible for routing traffic destined for the
-        configured <code>remote_ip</code>.  This could be an internal interface
-        such as a bridge port.
-      </column>
-
       <column name="other_config">
         Key-value pairs for rarely used interface features.  Currently,
         there are none defined.