From 093e47f48757beebd9a25e65f9cc5afa4328aabf Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 11 Dec 2009 17:03:35 -0800 Subject: [PATCH] vswitch: Set datapath_id and ofport in ovsdb. 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 | 40 ++++++++++++++++++++++++++++++++++--- vswitchd/vswitch-idl.ovsidl | 14 ++++++++----- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 20557773..c7aff74a 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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); diff --git a/vswitchd/vswitch-idl.ovsidl b/vswitchd/vswitch-idl.ovsidl index 1df9e920..2124c3c2 100644 --- a/vswitchd/vswitch-idl.ovsidl +++ b/vswitchd/vswitch-idl.ovsidl @@ -33,11 +33,9 @@ "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"}}}}, -- 2.30.2