hi,
This a patch for performance optimization when adding lots of ports.
The patch is based on version 2.3.0, and I have run all the testsuites.
The main optimize points are :
1) monitor some special records instead of monitor all the records
2) remove column "ports" in table "Bridge", replaced with adding "bridges" in
table "Port"
At 2014-11-25 23:40:09, "Ben Pfaff" <[email protected]> wrote:
>On Tue, Nov 25, 2014 at 05:36:31PM +0800, ychen wrote:
>> I have found that when adding lots of ports, system consumes more and
>> more time when ports number increasing.
>> And the main time is consumed on encapsulation and decapsulation the JSON
>> message between vsctl and ovsdb-server.
>> when vsctl starts, it will first send monitor request to ovsdb-server, and
>> then db-server send all the records with the related column to vsctl
>> please notice the word "all records", so that when ports number gets
>> larger, system will need more time to encap and decap the JSON message
>> between vsctl and db-server.
>>
>>
>> I suggest to slightly modify the RPC method "Monitor" in RFC 7047. The
>> main idea is only monitor specified records when add /del/set/get port.
>> The original Monitor method is like that:
>> Each <monitor-request> is an object with the following members:
>> "columns": [<column>*] optional
>> "select": <monitor-select> optional
>> The columns, if present, define the columns within the table to be
>> monitored. <monitor-select> is an object with the following members:
>> "initial": <boolean> optional
>> "insert": <boolean> optional
>> "delete": <boolean> optional
>>
>> "modify": <boolean> optional
>> And I want give this method a slight change:
>> <monitor-select> is an object with the following members:
>> "initial": <boolean> optional
>> "insert": <boolean> optional
>> "delete": <boolean> optional
>>
>> "modify": <boolean> optional
>> "where": [<condition>*] optional
>> for example, when add or del a port p0, first we will send a monitor request
>> like this:
>> method="monitor",
>> params=["Open_vSwitch",null,{"Port":{"columns":["bridges","fake_bridge","interfaces","name","tag"],"select":{"where":[["name","==","p0"]]}},"Interface":{"columns":["name","ofport","type"],"select":{"where":[["name","==","p0"]]}},"Bridge":{"columns":["controller","fail_mode","name"],"select":{"where":[["name","==","br0"]]}},"Controller":{"columns":[]},"Open_vSwitch":{"columns":["bridges","cur_cfg"]}}]
>> then ovsdb-server should only reply with the specified record p0, so that we
>> can save lots of time when monitoring.
>> I have done a test with this method, with 4000 ports, the time consuming can
>> be decreased from about 2800s to about 500s.
>
>Sounds great, please submit patches when you have them ready.
diff --git a/openvswitch-2.3.0/lib/ovsdb-idl-provider.h
b/openvswitch-2.3.0/lib/ovsdb-idl-provider.h
old mode 100644
new mode 100755
index 7ea5ce6..9643260
--- a/openvswitch-2.3.0/lib/ovsdb-idl-provider.h
+++ b/openvswitch-2.3.0/lib/ovsdb-idl-provider.h
@@ -46,6 +46,17 @@ struct ovsdb_idl_column {
void (*unparse)(struct ovsdb_idl_row *);
};
+struct ovsdb_idl_clause {
+ /*the condition function now will always use "=="*/
+ const struct ovsdb_idl_column *column;
+ struct ovsdb_datum arg;
+};
+
+struct ovsdb_idl_condition {
+ struct ovsdb_idl_clause *clauses;
+ size_t n_clauses;
+};
+
struct ovsdb_idl_table_class {
char *name;
bool is_root;
@@ -57,6 +68,7 @@ struct ovsdb_idl_table_class {
struct ovsdb_idl_table {
const struct ovsdb_idl_table_class *class;
+ struct ovsdb_idl_condition cnd; /*only for monitor optimize, select
specified records*/
unsigned char *modes; /* OVSDB_IDL_* bitmasks, indexed by column. */
bool need_table; /* Monitor table even if no columns? */
struct shash columns; /* Contains "const struct ovsdb_idl_column *"s. */
diff --git a/openvswitch-2.3.0/lib/ovsdb-idl.c
b/openvswitch-2.3.0/lib/ovsdb-idl.c
old mode 100644
new mode 100755
index 5c4d93b..e582f13
--- a/openvswitch-2.3.0/lib/ovsdb-idl.c
+++ b/openvswitch-2.3.0/lib/ovsdb-idl.c
@@ -159,6 +159,60 @@ static void ovsdb_idl_parse_lock_reply(struct ovsdb_idl *,
static void ovsdb_idl_parse_lock_notify(struct ovsdb_idl *,
const struct json *params,
bool new_has_lock);
+static void
+ovsdb_idl_condition_destroy(struct ovsdb_idl_condition *cnd)
+{
+ size_t i;
+ struct ovsdb_idl_clause *clause;
+
+ for (i = 0; i < cnd->n_clauses; i++) {
+ clause = &cnd->clauses[i];
+ ovsdb_datum_destroy(&clause->arg, &clause->column->type);
+ }
+ free(cnd->clauses);
+}
+
+void
+ovsdb_idl_add_condition(struct ovsdb_idl *idl, const struct
ovsdb_idl_table_class *tc,
+ const struct ovsdb_idl_column *column, struct ovsdb_datum
*datum)
+{
+ struct ovsdb_idl_table *table;
+ size_t i;
+
+ /*Get table*/
+ for (i = 0; i < idl->class->n_tables; i++) {
+ table = &idl->tables[i];
+
+ if (table->class == tc) {
+ break;
+ }
+ }
+
+ /*Select records which is indexed by name column, so all the column in
same table should be same*/
+ if (table->cnd.n_clauses
+ && table->cnd.clauses[0].column != column) {
+ VLOG_WARN("Only allow select the indexes column");
+ ovsdb_datum_destroy(datum, &column->type);
+ return;
+ }
+
+ /*Check duplicate records*/
+ for (i = 0; i < table->cnd.n_clauses; i++) {
+ if (ovsdb_datum_equals(datum, &table->cnd.clauses[i].arg,
&column->type)) {
+ ovsdb_datum_destroy(datum, &column->type);
+ return;
+ }
+ }
+
+ /*Set condition*/
+ if (table->cnd.n_clauses) {
+ table->cnd.clauses = xrealloc(table->cnd.clauses,
+ (table->cnd.n_clauses + 1) * sizeof
*table->cnd.clauses);
+ }
+ table->cnd.clauses[table->cnd.n_clauses].column = column;
+ table->cnd.clauses[table->cnd.n_clauses].arg = *datum;
+ table->cnd.n_clauses += 1;
+}
/* Creates and returns a connection to database 'remote', which should be in a
* form acceptable to jsonrpc_session_open(). The connection will maintain an
@@ -213,6 +267,9 @@ ovsdb_idl_create(const char *remote, const struct
ovsdb_idl_class *class,
}
hmap_init(&table->rows);
table->idl = idl;
+
+ table->cnd.clauses = xzalloc(sizeof *table->cnd.clauses);
+ table->cnd.n_clauses = 0;
}
idl->last_monitor_request_seqno = UINT_MAX;
hmap_init(&idl->outstanding_txns);
@@ -236,6 +293,7 @@ ovsdb_idl_destroy(struct ovsdb_idl *idl)
shash_destroy(&table->columns);
hmap_destroy(&table->rows);
free(table->modes);
+ ovsdb_idl_condition_destroy(&table->cnd);
}
shash_destroy(&idl->table_by_name);
free(idl->tables);
@@ -549,7 +607,16 @@ ovsdb_idl_omit(struct ovsdb_idl *idl, const struct
ovsdb_idl_column *column)
{
*ovsdb_idl_get_mode(idl, column) = 0;
}
-
+
+static struct json *
+where_condition_equals(struct ovsdb_idl_clause *clause)
+{
+ return json_array_create_3(
+ json_string_create(clause->column->name),
+ json_string_create("=="),
+ ovsdb_datum_to_json(&clause->arg, &clause->column->type));
+}
+
static void
ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
{
@@ -562,6 +629,7 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
const struct ovsdb_idl_table *table = &idl->tables[i];
const struct ovsdb_idl_table_class *tc = table->class;
struct json *monitor_request, *columns;
+ struct json *selects, *cnds;
size_t j;
columns = table->need_table ? json_array_create_empty() : NULL;
@@ -574,10 +642,26 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
json_array_add(columns, json_string_create(column->name));
}
}
+
+ cnds = NULL; /*must be initialized in every loop*/
+ selects = NULL; /*must be initialized in every loop*/
+ for (j = 0; j < table->cnd.n_clauses && columns; j++) {
+ if (!cnds) {
+ cnds = json_array_create_empty();
+ }
+ json_array_add(cnds,
where_condition_equals(&table->cnd.clauses[j]));
+ }
+ if (cnds){
+ selects = json_object_create();
+ json_object_put(selects, "where", cnds);
+ }
if (columns) {
monitor_request = json_object_create();
- json_object_put(monitor_request, "columns", columns);
+ json_object_put(monitor_request, "columns", columns);
+ if (selects) {
+ json_object_put(monitor_request, "select",
selects);
+ }
json_object_put(monitor_requests, tc->name, monitor_request);
}
}
diff --git a/openvswitch-2.3.0/lib/ovsdb-idl.h
b/openvswitch-2.3.0/lib/ovsdb-idl.h
index cb0ad11..f200a5b 100644
--- a/openvswitch-2.3.0/lib/ovsdb-idl.h
+++ b/openvswitch-2.3.0/lib/ovsdb-idl.h
@@ -217,4 +217,8 @@ const struct ovsdb_idl_row *ovsdb_idl_txn_insert(
struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *);
+void
+ovsdb_idl_add_condition(struct ovsdb_idl *, const struct ovsdb_idl_table_class
*,
+ const struct ovsdb_idl_column *, struct ovsdb_datum *);
+
#endif /* ovsdb-idl.h */
diff --git a/openvswitch-2.3.0/lib/vswitch-idl.c
b/openvswitch-2.3.0/lib/vswitch-idl.c
index a5a9559..fb9c1dc 100644
--- a/openvswitch-2.3.0/lib/vswitch-idl.c
+++ b/openvswitch-2.3.0/lib/vswitch-idl.c
@@ -304,27 +304,6 @@ ovsrec_bridge_parse_other_config(struct ovsdb_idl_row
*row_, const struct ovsdb_
}
static void
-ovsrec_bridge_parse_ports(struct ovsdb_idl_row *row_, const struct ovsdb_datum
*datum)
-{
- struct ovsrec_bridge *row = ovsrec_bridge_cast(row_);
- size_t i;
-
- ovs_assert(inited);
- row->ports = NULL;
- row->n_ports = 0;
- for (i = 0; i < datum->n; i++) {
- struct ovsrec_port *keyRow =
ovsrec_port_cast(ovsdb_idl_get_row_arc(row_,
&ovsrec_table_classes[OVSREC_TABLE_PORT], &datum->keys[i].uuid));
- if (keyRow) {
- if (!row->n_ports) {
- row->ports = xmalloc(datum->n * sizeof *row->ports);
- }
- row->ports[row->n_ports] = keyRow;
- row->n_ports++;
- }
- }
-}
-
-static void
ovsrec_bridge_parse_protocols(struct ovsdb_idl_row *row_, const struct
ovsdb_datum *datum)
{
struct ovsrec_bridge *row = ovsrec_bridge_cast(row_);
@@ -475,15 +454,6 @@ ovsrec_bridge_unparse_other_config(struct ovsdb_idl_row
*row_)
}
static void
-ovsrec_bridge_unparse_ports(struct ovsdb_idl_row *row_)
-{
- struct ovsrec_bridge *row = ovsrec_bridge_cast(row_);
-
- ovs_assert(inited);
- free(row->ports);
-}
-
-static void
ovsrec_bridge_unparse_protocols(struct ovsdb_idl_row *row_)
{
struct ovsrec_bridge *row = ovsrec_bridge_cast(row_);
@@ -644,13 +614,6 @@ ovsrec_bridge_verify_other_config(const struct
ovsrec_bridge *row)
}
void
-ovsrec_bridge_verify_ports(const struct ovsrec_bridge *row)
-{
- ovs_assert(inited);
- ovsdb_idl_txn_verify(&row->header_,
&ovsrec_bridge_columns[OVSREC_BRIDGE_COL_PORTS]);
-}
-
-void
ovsrec_bridge_verify_protocols(const struct ovsrec_bridge *row)
{
ovs_assert(inited);
@@ -963,29 +926,6 @@ ovsrec_bridge_get_other_config(const struct ovsrec_bridge
*row,
return ovsdb_idl_read(&row->header_, &ovsrec_bridge_col_other_config);
}
-/* Returns the ports column's value in 'row' as a struct ovsdb_datum.
- * This is useful occasionally: for example, ovsdb_datum_find_key() is an
- * easier and more efficient way to search for a given key than implementing
- * the same operation on the "cooked" form in 'row'.
- *
- * 'key_type' must be OVSDB_TYPE_UUID.
- * (This helps to avoid silent bugs if someone changes ports's
- * type without updating the caller.)
- *
- * The caller must not modify or free the returned value.
- *
- * Various kinds of changes can invalidate the returned value: modifying
- * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
- * If the returned value is needed for a long time, it is best to make a copy
- * of it with ovsdb_datum_clone(). */
-const struct ovsdb_datum *
-ovsrec_bridge_get_ports(const struct ovsrec_bridge *row,
- enum ovsdb_atomic_type key_type OVS_UNUSED)
-{
- ovs_assert(key_type == OVSDB_TYPE_UUID);
- return ovsdb_idl_read(&row->header_, &ovsrec_bridge_col_ports);
-}
-
/* Returns the protocols column's value in 'row' as a struct ovsdb_datum.
* This is useful occasionally: for example, ovsdb_datum_find_key() is an
* easier and more efficient way to search for a given key than implementing
@@ -1315,23 +1255,6 @@ ovsrec_bridge_set_other_config(const struct
ovsrec_bridge *row, const struct sma
void
-ovsrec_bridge_set_ports(const struct ovsrec_bridge *row, struct ovsrec_port
**ports, size_t n_ports)
-{
- struct ovsdb_datum datum;
- size_t i;
-
- ovs_assert(inited);
- datum.n = n_ports;
- datum.keys = n_ports ? xmalloc(n_ports * sizeof *datum.keys) : NULL;
- datum.values = NULL;
- for (i = 0; i < n_ports; i++) {
- datum.keys[i].uuid = ports[i]->header_.uuid;
- }
- ovsdb_datum_sort_unique(&datum, OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
- ovsdb_idl_txn_write(&row->header_,
&ovsrec_bridge_columns[OVSREC_BRIDGE_COL_PORTS], &datum);
-}
-
-void
ovsrec_bridge_set_protocols(const struct ovsrec_bridge *row, char **protocols,
size_t n_protocols)
{
struct ovsdb_datum datum;
@@ -1579,19 +1502,6 @@ ovsrec_bridge_columns_init(void)
c->parse = ovsrec_bridge_parse_other_config;
c->unparse = ovsrec_bridge_unparse_other_config;
- /* Initialize ovsrec_bridge_col_ports. */
- c = &ovsrec_bridge_col_ports;
- c->name = "ports";
- ovsdb_base_type_init(&c->type.key, OVSDB_TYPE_UUID);
- c->type.key.u.uuid.refTableName = "Port";
- c->type.key.u.uuid.refType = OVSDB_REF_STRONG;
- ovsdb_base_type_init(&c->type.value, OVSDB_TYPE_VOID);
- c->type.n_min = 0;
- c->type.n_max = UINT_MAX;
- c->mutable = true;
- c->parse = ovsrec_bridge_parse_ports;
- c->unparse = ovsrec_bridge_unparse_ports;
-
/* Initialize ovsrec_bridge_col_protocols. */
c = &ovsrec_bridge_col_protocols;
c->name = "protocols";
@@ -10696,6 +10606,19 @@ ovsrec_port_parse_bond_updelay(struct ovsdb_idl_row
*row_, const struct ovsdb_da
}
static void
+ovsrec_port_parse_bridges(struct ovsdb_idl_row *row_, const struct ovsdb_datum
*datum)
+{
+ struct ovsrec_port *row = ovsrec_port_cast(row_);
+
+ ovs_assert(inited);
+ if (datum->n >= 1) {
+ row->bridges = ovsrec_bridge_cast(ovsdb_idl_get_row_arc(row_,
&ovsrec_table_classes[OVSREC_TABLE_BRIDGE], &datum->keys[0].uuid));
+ } else {
+ row->bridges = NULL;
+ }
+}
+
+static void
ovsrec_port_parse_external_ids(struct ovsdb_idl_row *row_, const struct
ovsdb_datum *datum)
{
struct ovsrec_port *row = ovsrec_port_cast(row_);
@@ -10923,6 +10846,12 @@ ovsrec_port_unparse_bond_updelay(struct ovsdb_idl_row
*row OVS_UNUSED)
}
static void
+ovsrec_port_unparse_bridges(struct ovsdb_idl_row *row OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static void
ovsrec_port_unparse_external_ids(struct ovsdb_idl_row *row_)
{
struct ovsrec_port *row = ovsrec_port_cast(row_);
@@ -11097,6 +11026,13 @@ ovsrec_port_verify_bond_updelay(const struct
ovsrec_port *row)
}
void
+ovsrec_port_verify_bridges(const struct ovsrec_port *row)
+{
+ ovs_assert(inited);
+ ovsdb_idl_txn_verify(&row->header_,
&ovsrec_port_columns[OVSREC_PORT_COL_BRIDGES]);
+}
+
+void
ovsrec_port_verify_external_ids(const struct ovsrec_port *row)
{
ovs_assert(inited);
@@ -11279,6 +11215,29 @@ ovsrec_port_get_bond_updelay(const struct ovsrec_port
*row,
return ovsdb_idl_read(&row->header_, &ovsrec_port_col_bond_updelay);
}
+/* Returns the bridges column's value in 'row' as a struct ovsdb_datum.
+ * This is useful occasionally: for example, ovsdb_datum_find_key() is an
+ * easier and more efficient way to search for a given key than implementing
+ * the same operation on the "cooked" form in 'row'.
+ *
+ * 'key_type' must be OVSDB_TYPE_UUID.
+ * (This helps to avoid silent bugs if someone changes bridges's
+ * type without updating the caller.)
+ *
+ * The caller must not modify or free the returned value.
+ *
+ * Various kinds of changes can invalidate the returned value: modifying
+ * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
+ * If the returned value is needed for a long time, it is best to make a copy
+ * of it with ovsdb_datum_clone(). */
+const struct ovsdb_datum *
+ovsrec_port_get_bridges(const struct ovsrec_port *row,
+ enum ovsdb_atomic_type key_type OVS_UNUSED)
+{
+ ovs_assert(key_type == OVSDB_TYPE_UUID);
+ return ovsdb_idl_read(&row->header_, &ovsrec_port_col_bridges);
+}
+
/* Returns the external_ids column's value in 'row' as a struct ovsdb_datum.
* This is useful occasionally: for example, ovsdb_datum_find_key() is an
* easier and more efficient way to search for a given key than implementing
@@ -11652,6 +11611,20 @@ ovsrec_port_set_bond_updelay(const struct ovsrec_port
*row, int64_t bond_updelay
}
void
+ovsrec_port_set_bridges(const struct ovsrec_port *row, const struct
ovsrec_bridge *bridges)
+{
+ struct ovsdb_datum datum;
+ union ovsdb_atom key;
+
+ ovs_assert(inited);
+ datum.n = 1;
+ datum.keys = &key;
+ key.uuid = bridges->header_.uuid;
+ datum.values = NULL;
+ ovsdb_idl_txn_write_clone(&row->header_,
&ovsrec_port_columns[OVSREC_PORT_COL_BRIDGES], &datum);
+}
+
+void
ovsrec_port_set_external_ids(const struct ovsrec_port *row, const struct smap
*smap)
{
struct ovsdb_datum datum;
@@ -11976,6 +11949,19 @@ ovsrec_port_columns_init(void)
c->parse = ovsrec_port_parse_bond_updelay;
c->unparse = ovsrec_port_unparse_bond_updelay;
+ /* Initialize ovsrec_port_col_bridges. */
+ c = &ovsrec_port_col_bridges;
+ c->name = "bridges";
+ ovsdb_base_type_init(&c->type.key, OVSDB_TYPE_UUID);
+ c->type.key.u.uuid.refTableName = "Bridge";
+ c->type.key.u.uuid.refType = OVSDB_REF_STRONG;
+ ovsdb_base_type_init(&c->type.value, OVSDB_TYPE_VOID);
+ c->type.n_min = 1;
+ c->type.n_max = 1;
+ c->mutable = true;
+ c->parse = ovsrec_port_parse_bridges;
+ c->unparse = ovsrec_port_unparse_bridges;
+
/* Initialize ovsrec_port_col_external_ids. */
c = &ovsrec_port_col_external_ids;
c->name = "external_ids";
@@ -13999,7 +13985,7 @@ struct ovsdb_idl_table_class
ovsrec_table_classes[OVSREC_N_TABLES] = {
{"Open_vSwitch", true,
ovsrec_open_vswitch_columns, ARRAY_SIZE(ovsrec_open_vswitch_columns),
sizeof(struct ovsrec_open_vswitch), ovsrec_open_vswitch_init__},
- {"Port", false,
+ {"Port", true,
ovsrec_port_columns, ARRAY_SIZE(ovsrec_port_columns),
sizeof(struct ovsrec_port), ovsrec_port_init__},
{"QoS", true,
diff --git a/openvswitch-2.3.0/lib/vswitch-idl.h
b/openvswitch-2.3.0/lib/vswitch-idl.h
index d4e6d48..696ce74 100644
--- a/openvswitch-2.3.0/lib/vswitch-idl.h
+++ b/openvswitch-2.3.0/lib/vswitch-idl.h
@@ -56,10 +56,6 @@ struct ovsrec_bridge {
/* other_config column. */
struct smap other_config;
- /* ports column. */
- struct ovsrec_port **ports;
- size_t n_ports;
-
/* protocols column. */
char **protocols;
size_t n_protocols;
@@ -87,7 +83,6 @@ enum {
OVSREC_BRIDGE_COL_NAME,
OVSREC_BRIDGE_COL_NETFLOW,
OVSREC_BRIDGE_COL_OTHER_CONFIG,
- OVSREC_BRIDGE_COL_PORTS,
OVSREC_BRIDGE_COL_PROTOCOLS,
OVSREC_BRIDGE_COL_SFLOW,
OVSREC_BRIDGE_COL_STATUS,
@@ -105,11 +100,10 @@ enum {
#define ovsrec_bridge_col_other_config
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_OTHER_CONFIG])
#define ovsrec_bridge_col_flood_vlans
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_FLOOD_VLANS])
#define ovsrec_bridge_col_controller
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_CONTROLLER])
-#define ovsrec_bridge_col_netflow
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_NETFLOW])
#define ovsrec_bridge_col_stp_enable
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_STP_ENABLE])
#define ovsrec_bridge_col_flow_tables
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_FLOW_TABLES])
#define ovsrec_bridge_col_external_ids
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_EXTERNAL_IDS])
-#define ovsrec_bridge_col_ports
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_PORTS])
+#define ovsrec_bridge_col_netflow
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_NETFLOW])
#define ovsrec_bridge_col_protocols
(ovsrec_bridge_columns[OVSREC_BRIDGE_COL_PROTOCOLS])
#define ovsrec_bridge_col_name (ovsrec_bridge_columns[OVSREC_BRIDGE_COL_NAME])
@@ -143,7 +137,6 @@ void ovsrec_bridge_verify_mirrors(const struct
ovsrec_bridge *);
void ovsrec_bridge_verify_name(const struct ovsrec_bridge *);
void ovsrec_bridge_verify_netflow(const struct ovsrec_bridge *);
void ovsrec_bridge_verify_other_config(const struct ovsrec_bridge *);
-void ovsrec_bridge_verify_ports(const struct ovsrec_bridge *);
void ovsrec_bridge_verify_protocols(const struct ovsrec_bridge *);
void ovsrec_bridge_verify_sflow(const struct ovsrec_bridge *);
void ovsrec_bridge_verify_status(const struct ovsrec_bridge *);
@@ -164,7 +157,6 @@ const struct ovsdb_datum *ovsrec_bridge_get_mirrors(const
struct ovsrec_bridge *
const struct ovsdb_datum *ovsrec_bridge_get_name(const struct ovsrec_bridge *,
enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_bridge_get_netflow(const struct ovsrec_bridge
*, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_bridge_get_other_config(const struct
ovsrec_bridge *, enum ovsdb_atomic_type key_type, enum ovsdb_atomic_type
value_type);
-const struct ovsdb_datum *ovsrec_bridge_get_ports(const struct ovsrec_bridge
*, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_bridge_get_protocols(const struct
ovsrec_bridge *, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_bridge_get_sflow(const struct ovsrec_bridge
*, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_bridge_get_status(const struct ovsrec_bridge
*, enum ovsdb_atomic_type key_type, enum ovsdb_atomic_type value_type);
@@ -182,7 +174,6 @@ void ovsrec_bridge_set_mirrors(const struct ovsrec_bridge
*, struct ovsrec_mirro
void ovsrec_bridge_set_name(const struct ovsrec_bridge *, const char *name);
void ovsrec_bridge_set_netflow(const struct ovsrec_bridge *, const struct
ovsrec_netflow *netflow);
void ovsrec_bridge_set_other_config(const struct ovsrec_bridge *, const struct
smap *);
-void ovsrec_bridge_set_ports(const struct ovsrec_bridge *, struct ovsrec_port
**ports, size_t n_ports);
void ovsrec_bridge_set_protocols(const struct ovsrec_bridge *, char
**protocols, size_t n_protocols);
void ovsrec_bridge_set_sflow(const struct ovsrec_bridge *, const struct
ovsrec_sflow *sflow);
void ovsrec_bridge_set_status(const struct ovsrec_bridge *, const struct smap
*);
@@ -1338,6 +1329,9 @@ struct ovsrec_port {
/* bond_updelay column. */
int64_t bond_updelay;
+ /* bridges column. */
+ struct ovsrec_bridge *bridges;
+
/* external_ids column. */
struct smap external_ids;
@@ -1388,6 +1382,7 @@ enum {
OVSREC_PORT_COL_BOND_FAKE_IFACE,
OVSREC_PORT_COL_BOND_MODE,
OVSREC_PORT_COL_BOND_UPDELAY,
+ OVSREC_PORT_COL_BRIDGES,
OVSREC_PORT_COL_EXTERNAL_IDS,
OVSREC_PORT_COL_FAKE_BRIDGE,
OVSREC_PORT_COL_INTERFACES,
@@ -1405,6 +1400,7 @@ enum {
};
#define ovsrec_port_col_status (ovsrec_port_columns[OVSREC_PORT_COL_STATUS])
+#define ovsrec_port_col_bridges (ovsrec_port_columns[OVSREC_PORT_COL_BRIDGES])
#define ovsrec_port_col_statistics
(ovsrec_port_columns[OVSREC_PORT_COL_STATISTICS])
#define ovsrec_port_col_qos (ovsrec_port_columns[OVSREC_PORT_COL_QOS])
#define ovsrec_port_col_name (ovsrec_port_columns[OVSREC_PORT_COL_NAME])
@@ -1444,6 +1440,7 @@ void ovsrec_port_verify_bond_downdelay(const struct
ovsrec_port *);
void ovsrec_port_verify_bond_fake_iface(const struct ovsrec_port *);
void ovsrec_port_verify_bond_mode(const struct ovsrec_port *);
void ovsrec_port_verify_bond_updelay(const struct ovsrec_port *);
+void ovsrec_port_verify_bridges(const struct ovsrec_port *);
void ovsrec_port_verify_external_ids(const struct ovsrec_port *);
void ovsrec_port_verify_fake_bridge(const struct ovsrec_port *);
void ovsrec_port_verify_interfaces(const struct ovsrec_port *);
@@ -1465,6 +1462,7 @@ const struct ovsdb_datum
*ovsrec_port_get_bond_downdelay(const struct ovsrec_por
const struct ovsdb_datum *ovsrec_port_get_bond_fake_iface(const struct
ovsrec_port *, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_port_get_bond_mode(const struct ovsrec_port
*, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_port_get_bond_updelay(const struct
ovsrec_port *, enum ovsdb_atomic_type key_type);
+const struct ovsdb_datum *ovsrec_port_get_bridges(const struct ovsrec_port *,
enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_port_get_external_ids(const struct
ovsrec_port *, enum ovsdb_atomic_type key_type, enum ovsdb_atomic_type
value_type);
const struct ovsdb_datum *ovsrec_port_get_fake_bridge(const struct ovsrec_port
*, enum ovsdb_atomic_type key_type);
const struct ovsdb_datum *ovsrec_port_get_interfaces(const struct ovsrec_port
*, enum ovsdb_atomic_type key_type);
@@ -1483,6 +1481,7 @@ void ovsrec_port_set_bond_downdelay(const struct
ovsrec_port *, int64_t bond_dow
void ovsrec_port_set_bond_fake_iface(const struct ovsrec_port *, bool
bond_fake_iface);
void ovsrec_port_set_bond_mode(const struct ovsrec_port *, const char
*bond_mode);
void ovsrec_port_set_bond_updelay(const struct ovsrec_port *, int64_t
bond_updelay);
+void ovsrec_port_set_bridges(const struct ovsrec_port *, const struct
ovsrec_bridge *bridges);
void ovsrec_port_set_external_ids(const struct ovsrec_port *, const struct
smap *);
void ovsrec_port_set_fake_bridge(const struct ovsrec_port *, bool fake_bridge);
void ovsrec_port_set_interfaces(const struct ovsrec_port *, struct
ovsrec_interface **interfaces, size_t n_interfaces);
diff --git a/openvswitch-2.3.0/lib/vswitch-idl.ovsidl
b/openvswitch-2.3.0/lib/vswitch-idl.ovsidl
index 871aaac..d3e0cba 100644
--- a/openvswitch-2.3.0/lib/vswitch-idl.ovsidl
+++ b/openvswitch-2.3.0/lib/vswitch-idl.ovsidl
@@ -1 +1 @@
-{"cksum":"1731605290
20602","idlHeader":"\"lib/vswitch-idl.h\"","idlPrefix":"ovsrec_","name":"Open_vSwitch","tables":{"Bridge":{"columns":{"controller":{"type":{"key":{"refTable":"Controller","type":"uuid"},"max":"unlimited","min":0}},"datapath_id":{"ephemeral":true,"type":{"key":"string","max":1,"min":0}},"datapath_type":{"type":"string"},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"fail_mode":{"type":{"key":{"enum":["set",["standalone","secure"]],"type":"string"},"max":1,"min":0}},"flood_vlans":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"flow_tables":{"type":{"key":{"maxInteger":254,"minInteger":0,"type":"integer"},"max":"unlimited","min":0,"value":{"refTable":"Flow_Table","type":"uuid"}}},"ipfix":{"type":{"key":{"refTable":"IPFIX","type":"uuid"},"max":1,"min":0}},"mirrors":{"type":{"key":{"refTable":"Mirror","type":"uuid"},"max":"unlimited","min":0}},"name":{"mutable":false,"type":"string"},"netflow":{"type":{"key":{"refTable":"NetFlow","type":"uuid"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"ports":{"type":{"key":{"refTable":"Port","type":"uuid"},"max":"unlimited","min":0}},"protocols":{"type":{"key":{"enum":["set",["OpenFlow10","OpenFlow11","OpenFlow12","OpenFlow13","OpenFlow14","OpenFlow15"]],"type":"string"},"max":"unlimited","min":0}},"sflow":{"type":{"key":{"refTable":"sFlow","type":"uuid"},"max":1,"min":0}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"stp_enable":{"type":"boolean"}},"indexes":[["name"]]},"Controller":{"columns":{"connection_mode":{"type":{"key":{"enum":["set",["in-band","out-of-band"]],"type":"string"},"max":1,"min":0}},"controller_burst_limit":{"type":{"key":{"minInteger":25,"type":"integer"},"max":1,"min":0}},"controller_rate_limit":{"type":{"key":{"minInteger":100,"type":"integer"},"max":1,"min":0}},"enable_async_messages":{"type":{"key":{"type":"boolean"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"inactivity_probe":{"type":{"key":"integer","max":1,"min":0}},"is_connected":{"ephemeral":true,"type":"boolean"},"local_gateway":{"type":{"key":{"type":"string"},"max":1,"min":0}},"local_ip":{"type":{"key":{"type":"string"},"max":1,"min":0}},"local_netmask":{"type":{"key":{"type":"string"},"max":1,"min":0}},"max_backoff":{"type":{"key":{"minInteger":1000,"type":"integer"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"role":{"ephemeral":true,"type":{"key":{"enum":["set",["other","master","slave"]],"type":"string"},"max":1,"min":0}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"target":{"type":"string"}}},"Flow_Sample_Collector_Set":{"columns":{"bridge":{"type":{"key":{"refTable":"Bridge","type":"uuid"},"max":1,"min":1}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":1}},"ipfix":{"type":{"key":{"refTable":"IPFIX","type":"uuid"},"max":1,"min":0}}},"indexes":[["id","bridge"]],"isRoot":true},"Flow_Table":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"flow_limit":{"type":{"key":{"minInteger":0,"type":"integer"},"max":1,"min":0}},"groups":{"type":{"key":"string","max":"unlimited","min":0}},"name":{"type":{"key":"string","max":1,"min":0}},"overflow_policy":{"type":{"key":{"enum":["set",["refuse","evict"]],"type":"string"},"max":1,"min":0}},"prefixes":{"type":{"key":"string","max":3,"min":0}}}},"IPFIX":{"columns":{"cache_active_timeout":{"type":{"key":{"maxInteger":4200,"minInteger":0,"type":"integer"},"max":1,"min":0}},"cache_max_flows":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"obs_domain_id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"obs_point_id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"sampling":{"type":{"key":{"maxInteger":4294967295,"minInteger":1,"type":"integer"},"max":1,"min":0}},"targets":{"type":{"key":"string","max":"unlimited","min":0}}}},"Interface":{"columns":{"admin_state":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"bfd":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"bfd_status":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"cfm_fault":{"ephemeral":true,"type":{"key":{"type":"boolean"},"max":1,"min":0}},"cfm_fault_status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0}},"cfm_flap_count":{"type":{"key":{"type":"integer"},"max":1,"min":0}},"cfm_health":{"ephemeral":true,"type":{"key":{"maxInteger":100,"minInteger":0,"type":"integer"},"max":1,"min":0}},"cfm_mpid":{"type":{"key":{"type":"integer"},"max":1,"min":0}},"cfm_remote_mpids":{"ephemeral":true,"type":{"key":{"type":"integer"},"max":"unlimited","min":0}},"cfm_remote_opstate":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"duplex":{"ephemeral":true,"type":{"key":{"enum":["set",["half","full"]],"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"ifindex":{"ephemeral":true,"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"ingress_policing_burst":{"type":{"key":{"minInteger":0,"type":"integer"}}},"ingress_policing_rate":{"type":{"key":{"minInteger":0,"type":"integer"}}},"lacp_current":{"ephemeral":true,"type":{"key":{"type":"boolean"},"max":1,"min":0}},"link_resets":{"ephemeral":true,"type":{"key":{"type":"integer"},"max":1,"min":0}},"link_speed":{"ephemeral":true,"type":{"key":"integer","max":1,"min":0}},"link_state":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"mac":{"type":{"key":{"type":"string"},"max":1,"min":0}},"mac_in_use":{"ephemeral":true,"type":{"key":{"type":"string"},"max":1,"min":0}},"mtu":{"ephemeral":true,"type":{"key":"integer","max":1,"min":0}},"name":{"mutable":false,"type":"string"},"ofport":{"type":{"key":"integer","max":1,"min":0}},"ofport_request":{"type":{"key":{"maxInteger":65279,"minInteger":1,"type":"integer"},"max":1,"min":0}},"options":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"type":{"type":"string"}},"indexes":[["name"]]},"Manager":{"columns":{"connection_mode":{"type":{"key":{"enum":["set",["in-band","out-of-band"]],"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"inactivity_probe":{"type":{"key":"integer","max":1,"min":0}},"is_connected":{"ephemeral":true,"type":"boolean"},"max_backoff":{"type":{"key":{"minInteger":1000,"type":"integer"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"target":{"type":"string"}},"indexes":[["target"]]},"Mirror":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"name":{"type":"string"},"output_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":1,"min":0}},"output_vlan":{"type":{"key":{"maxInteger":4095,"minInteger":1,"type":"integer"},"max":1,"min":0}},"select_all":{"type":"boolean"},"select_dst_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":"unlimited","min":0}},"select_src_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":"unlimited","min":0}},"select_vlan":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}}}},"NetFlow":{"columns":{"active_timeout":{"type":{"key":{"minInteger":-1,"type":"integer"}}},"add_id_to_interface":{"type":"boolean"},"engine_id":{"type":{"key":{"maxInteger":255,"minInteger":0,"type":"integer"},"max":1,"min":0}},"engine_type":{"type":{"key":{"maxInteger":255,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"targets":{"type":{"key":{"type":"string"},"max":"unlimited","min":1}}}},"Open_vSwitch":{"columns":{"bridges":{"type":{"key":{"refTable":"Bridge","type":"uuid"},"max":"unlimited","min":0}},"cur_cfg":{"type":"integer"},"db_version":{"type":{"key":{"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"manager_options":{"type":{"key":{"refTable":"Manager","type":"uuid"},"max":"unlimited","min":0}},"next_cfg":{"type":"integer"},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"ovs_version":{"type":{"key":{"type":"string"},"max":1,"min":0}},"ssl":{"type":{"key":{"refTable":"SSL","type":"uuid"},"max":1,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"system_type":{"type":{"key":{"type":"string"},"max":1,"min":0}},"system_version":{"type":{"key":{"type":"string"},"max":1,"min":0}}},"isRoot":true,"maxRows":1},"Port":{"columns":{"bond_downdelay":{"type":"integer"},"bond_fake_iface":{"type":"boolean"},"bond_mode":{"type":{"key":{"enum":["set",["balance-tcp","balance-slb","active-backup"]],"type":"string"},"max":1,"min":0}},"bond_updelay":{"type":"integer"},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"fake_bridge":{"type":"boolean"},"interfaces":{"type":{"key":{"refTable":"Interface","type":"uuid"},"max":"unlimited","min":1}},"lacp":{"type":{"key":{"enum":["set",["active","passive","off"]],"type":"string"},"max":1,"min":0}},"mac":{"type":{"key":{"type":"string"},"max":1,"min":0}},"name":{"mutable":false,"type":"string"},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"qos":{"type":{"key":{"refTable":"QoS","type":"uuid"},"max":1,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"tag":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":1,"min":0}},"trunks":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"vlan_mode":{"type":{"key":{"enum":["set",["trunk","access","native-tagged","native-untagged"]],"type":"string"},"max":1,"min":0}}},"indexes":[["name"]]},"QoS":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"queues":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":"unlimited","min":0,"value":{"refTable":"Queue","type":"uuid"}}},"type":{"type":"string"}},"isRoot":true},"Queue":{"columns":{"dscp":{"type":{"key":{"maxInteger":63,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}}},"isRoot":true},"SSL":{"columns":{"bootstrap_ca_cert":{"type":"boolean"},"ca_cert":{"type":"string"},"certificate":{"type":"string"},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"private_key":{"type":"string"}},"maxRows":1},"sFlow":{"columns":{"agent":{"type":{"key":"string","max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"header":{"type":{"key":"integer","max":1,"min":0}},"polling":{"type":{"key":"integer","max":1,"min":0}},"sampling":{"type":{"key":"integer","max":1,"min":0}},"targets":{"type":{"key":"string","max":"unlimited","min":1}}}}},"version":"7.6.0"}
+{"cksum":"4178513122
20590","idlHeader":"\"lib/vswitch-idl.h\"","idlPrefix":"ovsrec_","name":"Open_vSwitch","tables":{"Bridge":{"columns":{"controller":{"type":{"key":{"refTable":"Controller","type":"uuid"},"max":"unlimited","min":0}},"datapath_id":{"ephemeral":true,"type":{"key":"string","max":1,"min":0}},"datapath_type":{"type":"string"},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"fail_mode":{"type":{"key":{"enum":["set",["standalone","secure"]],"type":"string"},"max":1,"min":0}},"flood_vlans":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"flow_tables":{"type":{"key":{"maxInteger":254,"minInteger":0,"type":"integer"},"max":"unlimited","min":0,"value":{"refTable":"Flow_Table","type":"uuid"}}},"ipfix":{"type":{"key":{"refTable":"IPFIX","type":"uuid"},"max":1,"min":0}},"mirrors":{"type":{"key":{"refTable":"Mirror","type":"uuid"},"max":"unlimited","min":0}},"name":{"mutable":false,"type":"string"},"netflow":{"type":{"key":{"refTable":"NetFlow","type":"uuid"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"protocols":{"type":{"key":{"enum":["set",["OpenFlow10","OpenFlow11","OpenFlow12","OpenFlow13","OpenFlow14","OpenFlow15"]],"type":"string"},"max":"unlimited","min":0}},"sflow":{"type":{"key":{"refTable":"sFlow","type":"uuid"},"max":1,"min":0}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"stp_enable":{"type":"boolean"}},"indexes":[["name"]]},"Controller":{"columns":{"connection_mode":{"type":{"key":{"enum":["set",["in-band","out-of-band"]],"type":"string"},"max":1,"min":0}},"controller_burst_limit":{"type":{"key":{"minInteger":25,"type":"integer"},"max":1,"min":0}},"controller_rate_limit":{"type":{"key":{"minInteger":100,"type":"integer"},"max":1,"min":0}},"enable_async_messages":{"type":{"key":{"type":"boolean"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"inactivity_probe":{"type":{"key":"integer","max":1,"min":0}},"is_connected":{"ephemeral":true,"type":"boolean"},"local_gateway":{"type":{"key":{"type":"string"},"max":1,"min":0}},"local_ip":{"type":{"key":{"type":"string"},"max":1,"min":0}},"local_netmask":{"type":{"key":{"type":"string"},"max":1,"min":0}},"max_backoff":{"type":{"key":{"minInteger":1000,"type":"integer"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"role":{"ephemeral":true,"type":{"key":{"enum":["set",["other","master","slave"]],"type":"string"},"max":1,"min":0}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"target":{"type":"string"}}},"Flow_Sample_Collector_Set":{"columns":{"bridge":{"type":{"key":{"refTable":"Bridge","type":"uuid"},"max":1,"min":1}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":1}},"ipfix":{"type":{"key":{"refTable":"IPFIX","type":"uuid"},"max":1,"min":0}}},"indexes":[["id","bridge"]],"isRoot":true},"Flow_Table":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"flow_limit":{"type":{"key":{"minInteger":0,"type":"integer"},"max":1,"min":0}},"groups":{"type":{"key":"string","max":"unlimited","min":0}},"name":{"type":{"key":"string","max":1,"min":0}},"overflow_policy":{"type":{"key":{"enum":["set",["refuse","evict"]],"type":"string"},"max":1,"min":0}},"prefixes":{"type":{"key":"string","max":3,"min":0}}}},"IPFIX":{"columns":{"cache_active_timeout":{"type":{"key":{"maxInteger":4200,"minInteger":0,"type":"integer"},"max":1,"min":0}},"cache_max_flows":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"obs_domain_id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"obs_point_id":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"sampling":{"type":{"key":{"maxInteger":4294967295,"minInteger":1,"type":"integer"},"max":1,"min":0}},"targets":{"type":{"key":"string","max":"unlimited","min":0}}}},"Interface":{"columns":{"admin_state":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"bfd":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"bfd_status":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"cfm_fault":{"ephemeral":true,"type":{"key":{"type":"boolean"},"max":1,"min":0}},"cfm_fault_status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0}},"cfm_flap_count":{"type":{"key":{"type":"integer"},"max":1,"min":0}},"cfm_health":{"ephemeral":true,"type":{"key":{"maxInteger":100,"minInteger":0,"type":"integer"},"max":1,"min":0}},"cfm_mpid":{"type":{"key":{"type":"integer"},"max":1,"min":0}},"cfm_remote_mpids":{"ephemeral":true,"type":{"key":{"type":"integer"},"max":"unlimited","min":0}},"cfm_remote_opstate":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"duplex":{"ephemeral":true,"type":{"key":{"enum":["set",["half","full"]],"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"ifindex":{"ephemeral":true,"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":1,"min":0}},"ingress_policing_burst":{"type":{"key":{"minInteger":0,"type":"integer"}}},"ingress_policing_rate":{"type":{"key":{"minInteger":0,"type":"integer"}}},"lacp_current":{"ephemeral":true,"type":{"key":{"type":"boolean"},"max":1,"min":0}},"link_resets":{"ephemeral":true,"type":{"key":{"type":"integer"},"max":1,"min":0}},"link_speed":{"ephemeral":true,"type":{"key":"integer","max":1,"min":0}},"link_state":{"ephemeral":true,"type":{"key":{"enum":["set",["up","down"]],"type":"string"},"max":1,"min":0}},"mac":{"type":{"key":{"type":"string"},"max":1,"min":0}},"mac_in_use":{"ephemeral":true,"type":{"key":{"type":"string"},"max":1,"min":0}},"mtu":{"ephemeral":true,"type":{"key":"integer","max":1,"min":0}},"name":{"mutable":false,"type":"string"},"ofport":{"type":{"key":"integer","max":1,"min":0}},"ofport_request":{"type":{"key":{"maxInteger":65279,"minInteger":1,"type":"integer"},"max":1,"min":0}},"options":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"type":{"type":"string"}},"indexes":[["name"]]},"Manager":{"columns":{"connection_mode":{"type":{"key":{"enum":["set",["in-band","out-of-band"]],"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"inactivity_probe":{"type":{"key":"integer","max":1,"min":0}},"is_connected":{"ephemeral":true,"type":"boolean"},"max_backoff":{"type":{"key":{"minInteger":1000,"type":"integer"},"max":1,"min":0}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"target":{"type":"string"}},"indexes":[["target"]]},"Mirror":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"name":{"type":"string"},"output_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":1,"min":0}},"output_vlan":{"type":{"key":{"maxInteger":4095,"minInteger":1,"type":"integer"},"max":1,"min":0}},"select_all":{"type":"boolean"},"select_dst_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":"unlimited","min":0}},"select_src_port":{"type":{"key":{"refTable":"Port","refType":"weak","type":"uuid"},"max":"unlimited","min":0}},"select_vlan":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}}}},"NetFlow":{"columns":{"active_timeout":{"type":{"key":{"minInteger":-1,"type":"integer"}}},"add_id_to_interface":{"type":"boolean"},"engine_id":{"type":{"key":{"maxInteger":255,"minInteger":0,"type":"integer"},"max":1,"min":0}},"engine_type":{"type":{"key":{"maxInteger":255,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"targets":{"type":{"key":{"type":"string"},"max":"unlimited","min":1}}}},"Open_vSwitch":{"columns":{"bridges":{"type":{"key":{"refTable":"Bridge","type":"uuid"},"max":"unlimited","min":0}},"cur_cfg":{"type":"integer"},"db_version":{"type":{"key":{"type":"string"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"manager_options":{"type":{"key":{"refTable":"Manager","type":"uuid"},"max":"unlimited","min":0}},"next_cfg":{"type":"integer"},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"ovs_version":{"type":{"key":{"type":"string"},"max":1,"min":0}},"ssl":{"type":{"key":{"refTable":"SSL","type":"uuid"},"max":1,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"system_type":{"type":{"key":{"type":"string"},"max":1,"min":0}},"system_version":{"type":{"key":{"type":"string"},"max":1,"min":0}}},"isRoot":true,"maxRows":1},"Port":{"columns":{"bond_downdelay":{"type":"integer"},"bond_fake_iface":{"type":"boolean"},"bond_mode":{"type":{"key":{"enum":["set",["balance-tcp","balance-slb","active-backup"]],"type":"string"},"max":1,"min":0}},"bond_updelay":{"type":"integer"},"bridges":{"type":{"key":{"refTable":"Bridge","type":"uuid"},"max":1,"min":1}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"fake_bridge":{"type":"boolean"},"interfaces":{"type":{"key":{"refTable":"Interface","type":"uuid"},"max":"unlimited","min":1}},"lacp":{"type":{"key":{"enum":["set",["active","passive","off"]],"type":"string"},"max":1,"min":0}},"mac":{"type":{"key":{"type":"string"},"max":1,"min":0}},"name":{"mutable":false,"type":"string"},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"qos":{"type":{"key":{"refTable":"QoS","type":"uuid"},"max":1,"min":0}},"statistics":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"integer"}},"status":{"ephemeral":true,"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"tag":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":1,"min":0}},"trunks":{"type":{"key":{"maxInteger":4095,"minInteger":0,"type":"integer"},"max":4096,"min":0}},"vlan_mode":{"type":{"key":{"enum":["set",["trunk","access","native-tagged","native-untagged"]],"type":"string"},"max":1,"min":0}}},"indexes":[["name"]],"isRoot":true},"QoS":{"columns":{"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"queues":{"type":{"key":{"maxInteger":4294967295,"minInteger":0,"type":"integer"},"max":"unlimited","min":0,"value":{"refTable":"Queue","type":"uuid"}}},"type":{"type":"string"}},"isRoot":true},"Queue":{"columns":{"dscp":{"type":{"key":{"maxInteger":63,"minInteger":0,"type":"integer"},"max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"other_config":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}}},"isRoot":true},"SSL":{"columns":{"bootstrap_ca_cert":{"type":"boolean"},"ca_cert":{"type":"string"},"certificate":{"type":"string"},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"private_key":{"type":"string"}},"maxRows":1},"sFlow":{"columns":{"agent":{"type":{"key":"string","max":1,"min":0}},"external_ids":{"type":{"key":"string","max":"unlimited","min":0,"value":"string"}},"header":{"type":{"key":"integer","max":1,"min":0}},"polling":{"type":{"key":"integer","max":1,"min":0}},"sampling":{"type":{"key":"integer","max":1,"min":0}},"targets":{"type":{"key":"string","max":"unlimited","min":1}}}}},"version":"7.6.0"}
diff --git a/openvswitch-2.3.0/ovsdb/condition.c
b/openvswitch-2.3.0/ovsdb/condition.c
old mode 100644
new mode 100755
index 8e67c88..8ed3dc2
--- a/openvswitch-2.3.0/ovsdb/condition.c
+++ b/openvswitch-2.3.0/ovsdb/condition.c
@@ -280,6 +280,26 @@ ovsdb_condition_evaluate(const struct ovsdb_row *row,
return true;
}
+bool
+ovsdb_condition_evaluate2(const struct ovsdb_row *row,
+ const struct ovsdb_condition *cnd)
+{
+ size_t i;
+
+ if (!cnd->n_clauses) {
+ return true;
+ }
+
+ for (i = 0; i < cnd->n_clauses; i++) {
+ if (ovsdb_clause_evaluate(row, &cnd->clauses[i])) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
void
ovsdb_condition_destroy(struct ovsdb_condition *cnd)
{
diff --git a/openvswitch-2.3.0/ovsdb/condition.h
b/openvswitch-2.3.0/ovsdb/condition.h
old mode 100644
new mode 100755
index ae6159c..e742ffc
--- a/openvswitch-2.3.0/ovsdb/condition.h
+++ b/openvswitch-2.3.0/ovsdb/condition.h
@@ -68,5 +68,8 @@ struct json *ovsdb_condition_to_json(const struct
ovsdb_condition *);
void ovsdb_condition_destroy(struct ovsdb_condition *);
bool ovsdb_condition_evaluate(const struct ovsdb_row *,
const struct ovsdb_condition *);
+bool ovsdb_condition_evaluate2(const struct ovsdb_row *,
+ const struct ovsdb_condition *);
+
#endif /* ovsdb/condition.h */
diff --git a/openvswitch-2.3.0/ovsdb/jsonrpc-server.c
b/openvswitch-2.3.0/ovsdb/jsonrpc-server.c
old mode 100644
new mode 100755
index cfaa656..231ceeb
--- a/openvswitch-2.3.0/ovsdb/jsonrpc-server.c
+++ b/openvswitch-2.3.0/ovsdb/jsonrpc-server.c
@@ -38,6 +38,8 @@
#include "transaction.h"
#include "trigger.h"
#include "vlog.h"
+#include "condition.h"
+
VLOG_DEFINE_THIS_MODULE(ovsdb_jsonrpc_server);
@@ -1059,6 +1061,7 @@ struct ovsdb_jsonrpc_monitor_table {
/* This is the union (bitwise-OR) of the 'select' values in all of the
* members of 'columns' below. */
enum ovsdb_jsonrpc_monitor_selection select;
+ struct ovsdb_condition condition;
/* Columns being monitored. */
struct ovsdb_jsonrpc_monitor_column *columns;
@@ -1149,6 +1152,7 @@ ovsdb_jsonrpc_parse_monitor_request(struct
ovsdb_jsonrpc_monitor_table *mt,
const struct json *columns, *select_json;
struct ovsdb_parser parser;
struct ovsdb_error *error;
+ const struct json *where;
ovsdb_parser_init(&parser, monitor_request, "table %s", ts->name);
columns = ovsdb_parser_member(&parser, "columns", OP_ARRAY | OP_OPTIONAL);
@@ -1174,6 +1178,15 @@ ovsdb_jsonrpc_parse_monitor_request(struct
ovsdb_jsonrpc_monitor_table *mt,
if (parse_bool(&parser, "modify", true)) {
select |= OJMS_MODIFY;
}
+
+ where = ovsdb_parser_member(&parser, "where", OP_ARRAY |
OP_OPTIONAL);
+ if (where) {
+ ovsdb_condition_from_json(ts, where, NULL,
&mt->condition);
+ if (!select) {
+ select = OJMS_INITIAL | OJMS_INSERT |
OJMS_DELETE | OJMS_MODIFY;
+ }
+ }
+
error = ovsdb_parser_finish(&parser);
if (error) {
return error;
@@ -1277,7 +1290,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session
*s, struct ovsdb *db,
mt = xzalloc(sizeof *mt);
mt->table = table;
hmap_init(&mt->changes);
- shash_add(&m->tables, table->schema->name, mt);
+ shash_add(&m->tables, table->schema->name, mt);
/* Parse columns. */
mr_value = node->data;
@@ -1487,6 +1500,10 @@ ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row
*old,
}
}
mt = aux->mt;
+
+ if (!ovsdb_condition_evaluate2((new ? new : old), &mt->condition)) {
+ return true; /*does not match the condition, do not consider
this record as changed*/
+ }
change = ovsdb_jsonrpc_monitor_row_find(mt, uuid);
if (!change) {
@@ -1761,6 +1778,7 @@ ovsdb_jsonrpc_monitor_destroy(struct ovsdb_replica
*replica)
ovsdb_jsonrpc_monitor_row_destroy(mt, row);
}
hmap_destroy(&mt->changes);
+ ovsdb_condition_destroy(&mt->condition);
free(mt->columns);
free(mt);
diff --git a/openvswitch-2.3.0/utilities/ovs-vsctl.c
b/openvswitch-2.3.0/utilities/ovs-vsctl.c
old mode 100644
new mode 100755
index 4fcee77..0fdba19
--- a/openvswitch-2.3.0/utilities/ovs-vsctl.c
+++ b/openvswitch-2.3.0/utilities/ovs-vsctl.c
@@ -841,15 +841,12 @@ vsctl_context_to_string(const struct vsctl_context *ctx)
static void
verify_ports(struct vsctl_context *ctx)
{
- if (!ctx->verified_ports) {
- const struct ovsrec_bridge *bridge;
+ if (!ctx->verified_ports) {
const struct ovsrec_port *port;
- ovsrec_open_vswitch_verify_bridges(ctx->ovs);
- OVSREC_BRIDGE_FOR_EACH (bridge, ctx->idl) {
- ovsrec_bridge_verify_ports(bridge);
- }
+ ovsrec_open_vswitch_verify_bridges(ctx->ovs);
OVSREC_PORT_FOR_EACH (port, ctx->idl) {
+ ovsrec_port_verify_bridges(port);
ovsrec_port_verify_interfaces(port);
}
@@ -1023,13 +1020,13 @@ pre_get_info(struct vsctl_context *ctx)
ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_name);
ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
- ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
- ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ports);
+ ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_name);
ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_fake_bridge);
ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_tag);
ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_interfaces);
+ ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_bridges);
ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_name);
ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_ofport);
@@ -1039,8 +1036,15 @@ static void
vsctl_context_populate_cache(struct vsctl_context *ctx)
{
const struct ovsrec_open_vswitch *ovs = ctx->ovs;
+ struct ovsrec_bridge *br_cfg;
+ struct ovsrec_port *port_cfg;
+ struct ovsrec_interface *iface_cfg;
+ struct vsctl_bridge *br;
+ struct vsctl_port *port;
+ struct vsctl_iface *iface;
struct sset bridges, ports;
- size_t i;
+ const struct ovsrec_port *port_node;
+ size_t i, k;
if (ctx->cache_valid) {
/* Cache is already populated. */
@@ -1051,13 +1055,12 @@ vsctl_context_populate_cache(struct vsctl_context *ctx)
shash_init(&ctx->ports);
shash_init(&ctx->ifaces);
+ /*Get bridges*/
sset_init(&bridges);
- sset_init(&ports);
- for (i = 0; i < ovs->n_bridges; i++) {
- struct ovsrec_bridge *br_cfg = ovs->bridges[i];
- struct vsctl_bridge *br;
- size_t j;
-
+ sset_init(&ports);
+ for (i = 0; i < ovs->n_bridges; i++) {
+ br_cfg = ovs->bridges[i];
+
if (!sset_add(&bridges, br_cfg->name)) {
VLOG_WARN("%s: database contains duplicate bridge name",
br_cfg->name);
@@ -1068,10 +1071,13 @@ vsctl_context_populate_cache(struct vsctl_context *ctx)
continue;
}
- for (j = 0; j < br_cfg->n_ports; j++) {
- struct ovsrec_port *port_cfg = br_cfg->ports[j];
-
- if (!sset_add(&ports, port_cfg->name)) {
+ OVSREC_PORT_FOR_EACH (port_node, ctx->idl) {
+ port_cfg = (struct ovsrec_port *)port_node;
+
+ if (port_cfg->bridges != br_cfg) {
+ continue;
+ }
+ if (!sset_add(&ports, port_cfg->name)) {
/* Duplicate port name. (We will warn about that later.) */
continue;
}
@@ -1081,74 +1087,67 @@ vsctl_context_populate_cache(struct vsctl_context *ctx)
add_bridge_to_cache(ctx, NULL, port_cfg->name, br,
*port_cfg->tag);
}
- }
- }
- sset_destroy(&bridges);
+ }
+ }
+ sset_destroy(&bridges);
sset_destroy(&ports);
+ /*Get Ports*/
sset_init(&bridges);
- for (i = 0; i < ovs->n_bridges; i++) {
- struct ovsrec_bridge *br_cfg = ovs->bridges[i];
- struct vsctl_bridge *br;
- size_t j;
+ OVSREC_PORT_FOR_EACH (port_node, ctx->idl) {
+ port_cfg = (struct ovsrec_port *)port_node;
+
+ /*Check bridge exists*/
+ br = shash_find_data(&ctx->bridges, port_cfg->bridges->name);
+ if (NULL == br || br->br_cfg != port_cfg->bridges) {
+ VLOG_ERR("Port %s: bridge %s does not exist",
+ port_cfg->name, port_cfg->bridges->name);
+ continue;
+ }
- if (!sset_add(&bridges, br_cfg->name)) {
+ port = shash_find_data(&ctx->ports, port_cfg->name);
+ if (port) {
+ if (port_cfg->bridges != port->port_cfg->bridges) {
+ VLOG_WARN("%s: port is in multiple bridges (%s and %s)",
+ port_cfg->name, br->name, port->bridge->name);
+ } else {
+ /* Log as an error because this violates the database's
+ * uniqueness constraints, so the database server shouldn't
+ * have allowed it. */
+ VLOG_ERR("%s: database contains duplicate port name",
+ port_cfg->name);
+ }
continue;
}
- br = shash_find_data(&ctx->bridges, br_cfg->name);
- for (j = 0; j < br_cfg->n_ports; j++) {
- struct ovsrec_port *port_cfg = br_cfg->ports[j];
- struct vsctl_port *port;
- size_t k;
-
- port = shash_find_data(&ctx->ports, port_cfg->name);
- if (port) {
- if (port_cfg == port->port_cfg) {
- VLOG_WARN("%s: port is in multiple bridges (%s and %s)",
- port_cfg->name, br->name, port->bridge->name);
- } else {
- /* Log as an error because this violates the database's
- * uniqueness constraints, so the database server shouldn't
- * have allowed it. */
- VLOG_ERR("%s: database contains duplicate port name",
- port_cfg->name);
- }
- continue;
- }
- if (port_is_fake_bridge(port_cfg)
- && !sset_add(&bridges, port_cfg->name)) {
- continue;
- }
+ if (port_is_fake_bridge(port_cfg)
+ && !sset_add(&bridges, port_cfg->name)) {
+ continue;
+ }
- port = add_port_to_cache(ctx, br, port_cfg);
- for (k = 0; k < port_cfg->n_interfaces; k++) {
- struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
- struct vsctl_iface *iface;
-
- iface = shash_find_data(&ctx->ifaces, iface_cfg->name);
- if (iface) {
- if (iface_cfg == iface->iface_cfg) {
- VLOG_WARN("%s: interface is in multiple ports "
- "(%s and %s)",
- iface_cfg->name,
- iface->port->port_cfg->name,
- port->port_cfg->name);
- } else {
- /* Log as an error because this violates the database's
- * uniqueness constraints, so the database server
- * shouldn't have allowed it. */
- VLOG_ERR("%s: database contains duplicate interface "
- "name", iface_cfg->name);
- }
- continue;
- }
+ /*Get interfaces*/
+ port = add_port_to_cache(ctx, br, port_cfg);
+ for (k = 0; k < port_cfg->n_interfaces; k++) {
+ iface_cfg = port_cfg->interfaces[k];
- add_iface_to_cache(ctx, port, iface_cfg);
+ iface = shash_find_data(&ctx->ifaces, iface_cfg->name);
+ if (iface) {
+ if (iface_cfg == iface->iface_cfg) {
+ VLOG_WARN("%s: interface is in multiple ports (%s and %s)",
+ iface_cfg->name,iface->port->port_cfg->name,
+ port->port_cfg->name);
+ } else {
+ /* Log as an error because this violates the database's
uniqueness constraints, so the database server
+ shouldn't have allowed it. */
+ VLOG_ERR("%s: database contains duplicate interface name",
iface_cfg->name);
+ }
+ continue;
}
- }
- }
- sset_destroy(&bridges);
+ add_iface_to_cache(ctx, port, iface_cfg);
+ }
+ }
+
+ sset_destroy(&bridges);
}
static void
@@ -1242,37 +1241,6 @@ find_iface(struct vsctl_context *ctx, const char *name,
bool must_exist)
}
static void
-bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
-{
- struct ovsrec_port **ports;
- size_t i;
-
- ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
- for (i = 0; i < br->n_ports; i++) {
- ports[i] = br->ports[i];
- }
- ports[br->n_ports] = port;
- ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
- free(ports);
-}
-
-static void
-bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
-{
- struct ovsrec_port **ports;
- size_t i, n;
-
- ports = xmalloc(sizeof *br->ports * br->n_ports);
- for (i = n = 0; i < br->n_ports; i++) {
- if (br->ports[i] != port) {
- ports[n++] = br->ports[i];
- }
- }
- ovsrec_bridge_set_ports(br, ports, n);
- free(ports);
-}
-
-static void
ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
struct ovsrec_bridge *bridge)
{
@@ -1312,13 +1280,13 @@ static struct cmd_show_table cmd_show_tables[] = {
&ovsrec_bridge_col_name,
{&ovsrec_bridge_col_controller,
&ovsrec_bridge_col_fail_mode,
- &ovsrec_bridge_col_ports},
+ NULL},
false},
{&ovsrec_table_port,
&ovsrec_port_col_name,
{&ovsrec_port_col_tag,
- &ovsrec_port_col_trunks,
+ &ovsrec_port_col_bridges,
&ovsrec_port_col_interfaces},
false},
@@ -1429,6 +1397,10 @@ cmd_show_row(struct vsctl_context *ctx, const struct
ovsdb_idl_row *row,
break;
}
+ if (!strcmp(column->name, "bridges")) {
+ continue;
+ }
+
datum = ovsdb_idl_read(row, column);
if (column->type.key.type == OVSDB_TYPE_UUID &&
column->type.key.u.uuid.refTableName) {
@@ -1465,12 +1437,35 @@ cmd_show_row(struct vsctl_context *ctx, const struct
ovsdb_idl_row *row,
static void
cmd_show(struct vsctl_context *ctx)
{
- const struct ovsdb_idl_row *row;
-
- for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
- row; row = ovsdb_idl_next_row(row)) {
- cmd_show_row(ctx, row, 0);
- }
+ const struct ovsrec_open_vswitch *ovs_cfg;
+ const struct ovsrec_port *port_cfg;
+ struct ovsrec_bridge *br_cfg;
+ size_t i;
+
+ OVSREC_OPEN_VSWITCH_FOR_EACH(ovs_cfg, ctx->idl) {
+ /*openvswitch information show*/
+ ds_put_format(&ctx->output, UUID_FMT,
UUID_ARGS(&ovs_cfg->header_.uuid));
+ ds_put_char(&ctx->output, '\n');
+
+ /*bridge information show*/
+ for (i = 0; i < ovs_cfg->n_bridges; i++) {
+ br_cfg = ovs_cfg->bridges[i];
+ ds_put_char_multiple(&ctx->output, ' ', 1 * 4);
+ ds_put_format(&ctx->output, "%s %s", "Bridge",
br_cfg->name);
+ ds_put_char(&ctx->output, '\n');
+
+ /*port information show*/
+ OVSREC_PORT_FOR_EACH(port_cfg, ctx->idl){
+ if (port_cfg->bridges != br_cfg) {
+ continue;
+ }
+ cmd_show_row(ctx, &port_cfg->header_, 2);
+ }
+ /*port end*/
+ }
+ /*bridge end*/
+ }
+ /*ovs end*/
}
static void
@@ -1656,7 +1651,7 @@ cmd_add_br(struct vsctl_context *ctx)
br = ovsrec_bridge_insert(ctx->txn);
ovsrec_bridge_set_name(br, br_name);
- ovsrec_bridge_set_ports(br, &port, 1);
+ ovsrec_port_set_bridges(port, br);
ovs_insert_bridge(ctx->ovs, br);
} else {
@@ -1683,8 +1678,7 @@ cmd_add_br(struct vsctl_context *ctx)
ovsrec_port_set_interfaces(port, &iface, 1);
ovsrec_port_set_fake_bridge(port, true);
ovsrec_port_set_tag(port, &tag, 1);
-
- bridge_insert_port(br, port);
+ ovsrec_port_set_bridges(port, br);
}
post_db_reload_expect_iface(iface);
@@ -1694,11 +1688,7 @@ cmd_add_br(struct vsctl_context *ctx)
static void
del_port(struct vsctl_context *ctx, struct vsctl_port *port)
{
- struct vsctl_iface *iface, *next_iface;
-
- bridge_delete_port((port->bridge->parent
- ? port->bridge->parent->br_cfg
- : port->bridge->br_cfg), port->port_cfg);
+ struct vsctl_iface *iface, *next_iface;
LIST_FOR_EACH_SAFE (iface, next_iface, ifaces_node, &port->ifaces) {
del_cached_iface(ctx, iface);
@@ -1901,8 +1891,7 @@ cmd_list_ports(struct vsctl_context *ctx)
struct svec ports;
vsctl_context_populate_cache(ctx);
- br = find_bridge(ctx, ctx->argv[1], true);
- ovsrec_bridge_verify_ports(br->br_cfg ? br->br_cfg : br->parent->br_cfg);
+ br = find_bridge(ctx, ctx->argv[1], true);
svec_init(&ports);
LIST_FOR_EACH (port, ports_node, &br->ports) {
@@ -1988,6 +1977,11 @@ add_port(struct vsctl_context *ctx,
ovsrec_port_set_name(port, port_name);
ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
ovsrec_port_set_bond_fake_iface(port, fake_iface);
+ if (bridge->br_cfg) {
+ ovsrec_port_set_bridges(port, bridge->br_cfg);
+ } else if (bridge->parent) {
+ ovsrec_port_set_bridges(port, bridge->parent->br_cfg);
+ }
if (bridge->parent) {
int64_t tag = bridge->vlan;
@@ -1997,10 +1991,7 @@ add_port(struct vsctl_context *ctx,
for (i = 0; i < n_settings; i++) {
set_column(get_table("Port"), &port->header_, settings[i],
ctx->symtab);
- }
-
- bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
- : bridge->br_cfg), port);
+ }
vsctl_port = add_port_to_cache(ctx, bridge, port);
for (i = 0; i < n_ifaces; i++) {
@@ -2825,6 +2816,55 @@ pre_get_column(struct vsctl_context *ctx,
ovsdb_idl_add_column(ctx->idl, *columnp);
}
+static void
+pre_get_condition(struct vsctl_context *ctx,
+ const struct vsctl_table_class *vsctl_table, const char
*record_name)
+{
+ const struct ovsdb_idl_column *column;
+ struct ovsdb_datum datum;
+
+ /*Always disable table bridge condition check*/
+ if (strcmp (vsctl_table->class->name, "Port")
+ && strcmp (vsctl_table->class->name, "Interface")) {
+ return;
+ }
+
+ /*Get conditions*/
+ die_if_error(get_column(vsctl_table, "name", &column));
+ die_if_error(ovsdb_datum_from_string(&datum, &column->type,
record_name, NULL));
+
+ /*Set condition*/
+ ovsdb_idl_add_condition(ctx->idl, vsctl_table->class, column, &datum);
+}
+
+static void
+pre_cmd_add_port(struct vsctl_context *ctx)
+{
+ pre_get_info(ctx);
+ pre_get_condition(ctx, get_table("Port"), ctx->argv[1]);/*Getting local
port for fake bridge*/
+ pre_get_condition(ctx, get_table("Port"), ctx->argv[2]);
+ pre_get_condition(ctx, get_table("Interface"), ctx->argv[1]);/*Getting
local port for fake bridge*/
+ pre_get_condition(ctx, get_table("Interface"), ctx->argv[2]);
+ /*should fetch all the bridge information,
+ otherwise we can not check conflicts like add-port in differernt
bridge*/
+}
+
+static void
+pre_cmd_del_port(struct vsctl_context *ctx)
+{
+ const char *target = ctx->argv[ctx->argc - 1];
+
+ pre_get_info(ctx);
+ pre_get_condition(ctx, get_table("Port"), target);
+ pre_get_condition(ctx, get_table("Interface"), target);
+ if (ctx->argc == 3) {
+ pre_get_condition(ctx, get_table("Port"), ctx->argv[1]);/*Getting
local port for fake bridge*/
+ pre_get_condition(ctx, get_table("Interface"),
ctx->argv[1]);/*Getting local port for fake bridge*/
+ }
+ /*should fetch all the bridge information,
+ otherwise we can not check conflicts like add-port in differernt
bridge*/
+}
+
static char *
missing_operator_error(const char *arg, const char **allowed_operators,
size_t n_allowed)
@@ -3022,6 +3062,8 @@ pre_cmd_get(struct vsctl_context *ctx)
pre_parse_column_key_value(ctx, ctx->argv[i], table);
}
+
+ pre_get_condition(ctx, table, ctx->argv[2]);
}
static void
@@ -3195,6 +3237,10 @@ pre_cmd_list(struct vsctl_context *ctx)
table = pre_get_table(ctx, table_name);
pre_list_columns(ctx, table, column_names);
+
+ if (ctx->argc == 3) {
+ pre_get_condition(ctx, table, ctx->argv[2]);
+ }
}
static struct table *
@@ -3335,15 +3381,36 @@ pre_cmd_set(struct vsctl_context *ctx)
{
const char *table_name = ctx->argv[1];
const struct vsctl_table_class *table;
+ const struct ovsdb_idl_column *column;
+ char *key_string, *value_string;
+ char *error;
int i;
table = pre_get_table(ctx, table_name);
- for (i = 3; i < ctx->argc; i++) {
- const struct ovsdb_idl_column *column;
-
+ for (i = 3; i < ctx->argc; i++) {
column = pre_parse_column_key_value(ctx, ctx->argv[i], table);
check_mutable(table, column);
}
+
+ pre_get_condition(ctx, table, ctx->argv[2]);
+
+ /*Get table Interface's patch port*/
+ if (strcmp(table->class->name, "Interface")) {
+ return;
+ }
+ for (i = 3; i < ctx->argc; i++) {
+ error = parse_column_key_value(ctx->argv[i], table, &column,
&key_string,
+ NULL, NULL, 0, &value_string);
+ if (error || !value_string) {
+ continue;
+ }
+
+ if (!strcmp(column->name, "options") && !strcmp(key_string,
"peer")) {
+ pre_get_condition(ctx, table, value_string);
+ table = pre_get_table(ctx, "Port");
+ pre_get_condition(ctx, table, value_string);
+ }
+ }
}
static void
@@ -3564,6 +3631,8 @@ pre_cmd_clear(struct vsctl_context *ctx)
pre_get_column(ctx, table, ctx->argv[i], &column);
check_mutable(table, column);
}
+
+ pre_get_condition(ctx, table, ctx->argv[2]);
}
static void
@@ -4259,11 +4328,11 @@ static const struct vsctl_command_syntax all_commands[]
= {
/* Port commands. */
{"list-ports", 1, 1, pre_get_info, cmd_list_ports, NULL, "", RO},
- {"add-port", 2, INT_MAX, pre_get_info, cmd_add_port, NULL, "--may-exist",
+ {"add-port", 2, INT_MAX, pre_cmd_add_port, cmd_add_port, NULL,
"--may-exist",
RW},
{"add-bond", 4, INT_MAX, pre_get_info, cmd_add_bond, NULL,
"--may-exist,--fake-iface", RW},
- {"del-port", 1, 2, pre_get_info, cmd_del_port, NULL,
+ {"del-port", 1, 2, pre_cmd_del_port, cmd_del_port, NULL,
"--if-exists,--with-iface", RW},
{"port-to-br", 1, 1, pre_get_info, cmd_port_to_br, NULL, "", RO},
diff --git a/openvswitch-2.3.0/vswitchd/bridge.c
b/openvswitch-2.3.0/vswitchd/bridge.c
old mode 100644
new mode 100755
index 5dcd3ba..9c1c3aa
--- a/openvswitch-2.3.0/vswitchd/bridge.c
+++ b/openvswitch-2.3.0/vswitchd/bridge.c
@@ -311,11 +311,13 @@ static void add_vlan_splinter_ports(struct bridge *,
struct shash *ports);
static void
-bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
+bridge_init_ofproto(const struct ovsdb_idl *idl)
{
struct shash iface_hints;
static bool initialized = false;
- int i;
+ const struct ovsrec_port *port_cfg;
+ struct ovsrec_bridge *br_cfg;
+ int k;
if (initialized) {
return;
@@ -323,29 +325,20 @@ bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
shash_init(&iface_hints);
- if (cfg) {
- for (i = 0; i < cfg->n_bridges; i++) {
- const struct ovsrec_bridge *br_cfg = cfg->bridges[i];
- int j;
-
- for (j = 0; j < br_cfg->n_ports; j++) {
- struct ovsrec_port *port_cfg = br_cfg->ports[j];
- int k;
-
- for (k = 0; k < port_cfg->n_interfaces; k++) {
- struct ovsrec_interface *if_cfg = port_cfg->interfaces[k];
- struct iface_hint *iface_hint;
+ OVSREC_PORT_FOR_EACH(port_cfg, idl){
+ for (k = 0; k < port_cfg->n_interfaces; k++) {
+ struct ovsrec_interface *if_cfg = port_cfg->interfaces[k];
+ struct iface_hint *iface_hint;
- iface_hint = xmalloc(sizeof *iface_hint);
- iface_hint->br_name = br_cfg->name;
- iface_hint->br_type = br_cfg->datapath_type;
- iface_hint->ofp_port = iface_pick_ofport(if_cfg);
+ br_cfg = port_cfg->bridges;
+ iface_hint = xmalloc(sizeof *iface_hint);
+ iface_hint->br_name = br_cfg->name;
+ iface_hint->br_type = br_cfg->datapath_type;
+ iface_hint->ofp_port = iface_pick_ofport(if_cfg);
- shash_add(&iface_hints, if_cfg->name, iface_hint);
- }
- }
+ shash_add(&iface_hints, if_cfg->name, iface_hint);
}
- }
+ }
ofproto_init(&iface_hints);
@@ -2295,7 +2288,7 @@ bridge_run(void)
* it must be done after the configuration is set. If the
* initialization has already occurred, bridge_init_ofproto()
* returns immediately. */
- bridge_init_ofproto(cfg);
+ bridge_init_ofproto(idl);
/* Once the value of flow-restore-wait is false, we no longer should
* check its value from the database. */
@@ -2758,17 +2751,21 @@ bridge_collect_wanted_ports(struct bridge *br,
const unsigned long int *splinter_vlans,
struct shash *wanted_ports)
{
- size_t i;
+ const struct ovsrec_port *port_cfg;
shash_init(wanted_ports);
- for (i = 0; i < br->cfg->n_ports; i++) {
- const char *name = br->cfg->ports[i]->name;
- if (!shash_add_once(wanted_ports, name, br->cfg->ports[i])) {
+ OVSREC_PORT_FOR_EACH(port_cfg, idl){
+ const char *name = port_cfg->name;
+ if (br->cfg != port_cfg->bridges) {
+ continue;
+ }
+ if (!shash_add_once(wanted_ports, name, port_cfg)) {
VLOG_WARN("bridge %s: %s specified twice as bridge port",
br->name, name);
}
}
+
if (bridge_get_controllers(br, NULL)
&& !shash_find(wanted_ports, br->name)) {
VLOG_WARN("bridge %s: no port named %s, synthesizing one",
@@ -4044,7 +4041,7 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch
*ovs_cfg)
struct shash *real_devs;
struct shash_node *node;
struct bridge *br;
- size_t i;
+ const struct ovsrec_port *port_cfg;
/* Free space allocated for synthesized ports and interfaces, since we're
* in the process of reconstructing all of them. */
@@ -4053,30 +4050,24 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch
*ovs_cfg)
splinter_vlans = bitmap_allocate(4096);
sset_init(&splinter_ifaces);
vlan_splinters_enabled_anywhere = false;
- for (i = 0; i < ovs_cfg->n_bridges; i++) {
- struct ovsrec_bridge *br_cfg = ovs_cfg->bridges[i];
- size_t j;
-
- for (j = 0; j < br_cfg->n_ports; j++) {
- struct ovsrec_port *port_cfg = br_cfg->ports[j];
- int k;
-
- for (k = 0; k < port_cfg->n_interfaces; k++) {
- struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
+ OVSREC_PORT_FOR_EACH(port_cfg, idl) {
+ size_t k;
- if (vlan_splinters_is_enabled(iface_cfg)) {
- vlan_splinters_enabled_anywhere = true;
- sset_add(&splinter_ifaces, iface_cfg->name);
- vlan_bitmap_from_array__(port_cfg->trunks,
- port_cfg->n_trunks,
- splinter_vlans);
- }
- }
+ for (k = 0; k < port_cfg->n_interfaces; k++) {
+ struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
- if (port_cfg->tag && *port_cfg->tag > 0 && *port_cfg->tag < 4095) {
- bitmap_set1(splinter_vlans, *port_cfg->tag);
+ if (vlan_splinters_is_enabled(iface_cfg)) {
+ vlan_splinters_enabled_anywhere = true;
+ sset_add(&splinter_ifaces, iface_cfg->name);
+ vlan_bitmap_from_array__(port_cfg->trunks,
+ port_cfg->n_trunks,
+ splinter_vlans);
}
}
+
+ if (port_cfg->tag && *port_cfg->tag > 0 && *port_cfg->tag < 4095) {
+ bitmap_set1(splinter_vlans, *port_cfg->tag);
+ }
}
if (!vlan_splinters_enabled_anywhere) {
@@ -4207,14 +4198,21 @@ add_vlan_splinter_ports(struct bridge *br,
const unsigned long int *splinter_vlans,
struct shash *ports)
{
- size_t i;
+ const struct ovsrec_port *port_cfg;
/* We iterate through 'br->cfg->ports' instead of 'ports' here because
* we're modifying 'ports'. */
- for (i = 0; i < br->cfg->n_ports; i++) {
- const char *name = br->cfg->ports[i]->name;
- struct ovsrec_port *port_cfg = shash_find_data(ports, name);
- size_t j;
+ OVSREC_PORT_FOR_EACH(port_cfg, idl) {
+ const char *name = port_cfg->name;
+ size_t j;
+
+ if (br->cfg != port_cfg->bridges) {
+ continue;
+ }
+
+ if (shash_find_data(ports, name) != port_cfg) {
+ continue;
+ }
for (j = 0; j < port_cfg->n_interfaces; j++) {
struct ovsrec_interface *iface_cfg = port_cfg->interfaces[j];
diff --git a/openvswitch-2.3.0/vswitchd/vswitch.ovsschema
b/openvswitch-2.3.0/vswitchd/vswitch.ovsschema
index 006ed23..3288c30 100644
--- a/openvswitch-2.3.0/vswitchd/vswitch.ovsschema
+++ b/openvswitch-2.3.0/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
"version": "7.6.0",
- "cksum": "1731605290 20602",
+ "cksum": "4178513122 20590",
"tables": {
"Open_vSwitch": {
"columns": {
@@ -54,10 +54,6 @@
"ephemeral": true},
"stp_enable": {
"type": "boolean"},
- "ports": {
- "type": {"key": {"type": "uuid",
- "refTable": "Port"},
- "min": 0, "max": "unlimited"}},
"mirrors": {
"type": {"key": {"type": "uuid",
"refTable": "Mirror"},
@@ -116,6 +112,10 @@
"name": {
"type": "string",
"mutable": false},
+ "bridges": {
+ "type": {"key": {"type": "uuid",
+ "refTable": "Bridge"},
+ "min": 1, "max": 1}},
"interfaces": {
"type": {"key": {"type": "uuid",
"refTable": "Interface"},
@@ -167,7 +167,8 @@
"type": {"key": "string", "value": "string", "min": 0, "max":
"unlimited"}},
"external_ids": {
"type": {"key": "string", "value": "string", "min": 0, "max":
"unlimited"}}},
- "indexes": [["name"]]},
+ "indexes": [["name"]],
+ "isRoot": true},
"Interface": {
"columns": {
"name": {
diff --git a/openvswitch-2.3.0/vswitchd/vswitch.xml
b/openvswitch-2.3.0/vswitchd/vswitch.xml
index f160b01..b61adb9 100644
--- a/openvswitch-2.3.0/vswitchd/vswitch.xml
+++ b/openvswitch-2.3.0/vswitchd/vswitch.xml
@@ -443,10 +443,6 @@
bridges on a host.
</column>
- <column name="ports">
- Ports included in the bridge.
- </column>
-
<column name="mirrors">
Port mirroring configuration.
</column>
@@ -815,6 +811,10 @@
ports, interfaces, and bridges on a host.
</column>
+ <column name="bridges">
+ Which bridge does this port belong.
+ </column>
+
<column name="interfaces">
The port's interfaces. If there is more than one, this is a
bonded Port.
_______________________________________________
discuss mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/discuss