+handle_get_bridges_cmd(const struct ovsrec_open_vswitch *ovs,
+ struct ofpbuf *buffer)
+{
+ struct svec bridges;
+ size_t i, j;
+
+ uint32_t seq;
+
+ int error;
+
+ /* Parse Netlink command.
+ *
+ * The command doesn't actually have any arguments, but we need the
+ * sequence number to send the reply. */
+ error = parse_command(buffer, &seq, NULL, NULL, NULL, NULL);
+ if (error) {
+ return error;
+ }
+
+ /* Get all the real bridges and all the fake ones. */
+ svec_init(&bridges);
+ for (i = 0; i < ovs->n_bridges; i++) {
+ const struct ovsrec_bridge *br = ovs->bridges[i];
+
+ svec_add(&bridges, br->name);
+ for (j = 0; j < br->n_ports; j++) {
+ const struct ovsrec_port *port = br->ports[j];
+
+ if (port->fake_bridge) {
+ svec_add(&bridges, port->name);
+ }
+ }
+ }
+
+ send_ifindex_reply(seq, &bridges);
+ svec_destroy(&bridges);
+
+ return 0;
+}
+
+static int
+handle_get_ports_cmd(const struct ovsrec_open_vswitch *ovs,
+ struct ofpbuf *buffer)
+{
+ uint32_t seq;
+
+ const char *linux_name;
+ const struct ovsrec_bridge *ovs_bridge;
+ int br_vlan;
+
+ struct svec ports;
+
+ int error;
+
+ /* Parse Netlink command. */
+ error = parse_command(buffer, &seq, &linux_name, NULL, NULL, NULL);
+ if (error) {
+ return error;
+ }
+
+ error = linux_bridge_to_ovs_bridge(ovs, linux_name,
+ &ovs_bridge, &br_vlan);
+ if (error) {
+ send_simple_reply(seq, error);
+ return error;
+ }
+
+ svec_init(&ports);
+ get_bridge_ports(ovs_bridge, &ports, br_vlan);
+ svec_sort(&ports);
+ svec_del(&ports, linux_name);
+ send_ifindex_reply(seq, &ports); /* XXX bonds won't show up */
+ svec_destroy(&ports);
+
+ return 0;
+}
+
+static void
+brc_recv_update(struct ovsdb_idl *idl)