vswitch: Set datapath_id and ofport in ovsdb.
authorBen Pfaff <blp@nicira.com>
Sat, 12 Dec 2009 01:03:35 +0000 (17:03 -0800)
committerBen Pfaff <blp@nicira.com>
Sat, 12 Dec 2009 01:03:35 +0000 (17:03 -0800)
Now ovs-vswitchd fills in the Interface ofport and Bridge datapath_id
fields when it reconfigures.

The existing Bridge datapath_id and hwaddr columns, which had surprising
meanings, have been banished to a new other_config column.

vswitchd/bridge.c
vswitchd/vswitch-idl.ovsidl

index 205577738fe58e0b187b7a8539c6d50bd24d275d..c7aff74a8132e264c42fb0b5798ec1a02c748aa9 100644 (file)
@@ -517,6 +517,7 @@ iterate_and_prune_ifaces(struct bridge *br,
 void
 bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
 {
+    struct ovsdb_idl_txn *txn;
     struct shash old_br, new_br;
     struct shash_node *node;
     struct bridge *br, *next;
@@ -524,6 +525,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
 
     COVERAGE_INC(bridge_reconfigure);
 
+    txn = ovsdb_idl_txn_create(ovs_cfg->header_.table->idl);
+
     /* Collect old and new bridges. */
     shash_init(&old_br);
     shash_init(&new_br);
@@ -652,6 +655,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         uint64_t dpid;
         struct iface *local_iface;
         struct iface *hw_addr_iface;
+        char *dpid_string;
 
         bridge_fetch_dp_ifaces(br);
         iterate_and_prune_ifaces(br, init_iface_netdev, NULL);
@@ -674,6 +678,10 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         dpid = bridge_pick_datapath_id(br, ea, hw_addr_iface);
         ofproto_set_datapath_id(br->ofproto, dpid);
 
+        dpid_string = xasprintf("%012"PRIx64, dpid);
+        ovsrec_bridge_set_datapath_id(br->cfg, dpid_string);
+        free(dpid_string);
+
         /* Set NetFlow configuration on this bridge. */
         if (br->cfg->netflow) {
             struct ovsrec_netflow *nf_cfg = br->cfg->netflow;
@@ -745,19 +753,37 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
     LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
         iterate_and_prune_ifaces(br, set_iface_properties, NULL);
     }
+
+    ovsdb_idl_txn_commit(txn);
+    ovsdb_idl_txn_destroy(txn); /* XXX */
+}
+
+static const char *
+bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
+{
+    size_t i;
+
+    for (i = 0; i < br_cfg->n_other_config; i++) {
+        if (!strcmp(br_cfg->key_other_config[i], key)) {
+            return br_cfg->value_other_config[i];
+        }
+    }
+    return NULL;
 }
 
 static void
 bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
                           struct iface **hw_addr_iface)
 {
+    const char *hwaddr;
     size_t i, j;
     int error;
 
     *hw_addr_iface = NULL;
 
     /* Did the user request a particular MAC? */
-    if (br->cfg->hwaddr && eth_addr_from_string(br->cfg->hwaddr, ea)) {
+    hwaddr = bridge_get_other_config(br->cfg, "hwaddr");
+    if (hwaddr && eth_addr_from_string(hwaddr, ea)) {
         if (eth_addr_is_multicast(ea)) {
             VLOG_ERR("bridge %s: cannot set MAC address to multicast "
                      "address "ETH_ADDR_FMT, br->name, ETH_ADDR_ARGS(ea));
@@ -872,10 +898,11 @@ bridge_pick_datapath_id(struct bridge *br,
      * stable from one run to the next, so that policy set on a datapath
      * "sticks".
      */
+    const char *datapath_id;
     uint64_t dpid;
 
-    if (br->cfg->datapath_id
-        && dpid_from_string(br->cfg->datapath_id, &dpid)) {
+    datapath_id = bridge_get_other_config(br->cfg, "datapath-id");
+    if (datapath_id && dpid_from_string(datapath_id, &dpid)) {
         return dpid;
     }
 
@@ -1514,6 +1541,13 @@ bridge_fetch_dp_ifaces(struct bridge *br)
                 port_array_set(&br->ifaces, p->port, iface);
                 iface->dp_ifidx = p->port;
             }
+
+            if (iface->cfg) {
+                int64_t ofport = (iface->dp_ifidx >= 0
+                                  ? odp_port_to_ofp_port(iface->dp_ifidx)
+                                  : -1);
+                ovsrec_interface_set_ofport(iface->cfg, &ofport, 1);
+            }
         }
     }
     free(dpif_ports);
index 1df9e920684017a10416ade25894e97d156bd09c..2124c3c26b7d04160c47d478685cd6210d6f3737 100644 (file)
          "comment": "Bridge identifier.  Should be alphanumeric and no more than about 8 bytes long.  Must be unique among the names of ports, interfaces, and bridges on a host.",
          "type": "string"},
        "datapath_id": {
-         "comment": "OpenFlow datapath ID.  Exactly 12 hex digits.",
-         "type": {"key": "string", "min": 0, "max": 1}},
-       "hwaddr": {
-         "comment": "Ethernet address to use for bridge.  Exactly 12 hex digits in the form XX:XX:XX:XX:XX:XX.",
-         "type": {"key": "string", "min": 0, "max": 1}},
+         "comment": "Reports the OpenFlow datapath ID in use.  Exactly 12 hex digits.",
+         "type": {"key": "string", "min": 0, "max": 1},
+         "ephemeral": true},
        "ports": {
          "comment": "Ports included in the bridge.",
          "type": {"key": "uuid", "keyRefTable": "Port", "min": 0, "max": "unlimited"}},
@@ -50,6 +48,9 @@
        "controller": {
          "comment": "OpenFlow controller.  If unset, defaults to that specified by the parent Open_vSwitch.",
          "type": {"key": "uuid", "keyRefTable": "Controller", "min": 0, "max": 1}},
+       "other_config": {
+         "comment": "Key-value pairs for configuring rarely used bridge features.  The currently defined key-value pairs are: \"datapath-id\", exactly 12 hex digits to set the OpenFlow datapath ID to a specific value; \"hwaddr\", exactly 12 hex digits in the form \"XX:XX:XX:XX:XX:XX\" to set the hardware address of the local port and influence the datapath ID.",
+         "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}},
        "external_ids": {
          "comment": "Key-value pairs that identify this bridge's role in external systems.  The currently defined key-value pairs are: \"xs-network-uuid\", a space-delimited set of the Citrix XenServer network UUIDs with which this bridge is associated.",
          "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}},
@@ -83,6 +84,9 @@
        "fake_bridge": {
          "comment": "Does this port represent a sub-bridge for its tagged VLAN within the Bridge?  See ovs-vsctl(8) for more information.",
          "type": "boolean"},
+       "other_config": {
+         "comment": "Key-value pairs for configuring rarely used port features.  The currently defined key-value pairs are: \"hwaddr\", exactly 12 hex digits in the form \"XX:XX:XX:XX:XX:XX\".",
+         "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}},
        "external_ids": {
          "comment": "Key-value pairs that identify this port's role in external systems.  No key-value pairs native to Port are currently defined.  For fake bridges (see the \"fake-bridge\" column), external IDs for the fake bridge are defined here by prefixing their keys with \"fake-bridge\", e.g. \"fake-bridge-xs-network-uuids\".",
          "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}},