X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fovs-brcompatd.c;h=7f9602882dfa1e1a2b902461a4ffa798a4f9735e;hb=e3648418c4bf028e6bca38bcbfc5a5ed493447fb;hp=6b6594797a0b59f699158861ecfef5a33447896e;hpb=b959290bed1e2183ec93f593422e9ac4ae1a9587;p=openvswitch diff --git a/vswitchd/ovs-brcompatd.c b/vswitchd/ovs-brcompatd.c index 6b659479..7f960288 100644 --- a/vswitchd/ovs-brcompatd.c +++ b/vswitchd/ovs-brcompatd.c @@ -115,7 +115,7 @@ lookup_brc_multicast_group(int *multicast_group) return retval; } ofpbuf_init(&request, 0); - nl_msg_put_genlmsghdr(&request, sock, 0, brc_family, + nl_msg_put_genlmsghdr(&request, 0, brc_family, NLM_F_REQUEST, BRC_GENL_C_QUERY_MC, 1); retval = nl_sock_transact(sock, &request, &reply); ofpbuf_uninit(&request); @@ -280,68 +280,6 @@ get_bridge_ports(const struct ovsrec_bridge *br, struct svec *ports, do_get_bridge_parts(br, ports, vlan, false); } -#if 0 -/* Go through the configuration file and remove any ports that no longer - * exist associated with a bridge. */ -static void -prune_ports(void) -{ - int i, j; - struct svec bridges, delete; - - if (cfg_lock(NULL, 0)) { - /* Couldn't lock config file. */ - return; - } - - svec_init(&bridges); - svec_init(&delete); - cfg_get_subsections(&bridges, "bridge"); - for (i=0; iports * 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); + + /* Delete all of the port's interfaces. */ + for (i = 0; i < port->n_interfaces; i++) { + ovsrec_interface_delete(port->interfaces[i]); + } + + /* Delete the port itself. */ + ovsrec_port_delete(port); +} + +/* Delete 'iface' from 'port' (which must be within 'br'). If 'iface' was + * 'port''s only interface, delete 'port' from 'br' also. + * + * After calling this function, 'iface' must not be referenced again. */ +static void +del_interface(const struct ovsrec_bridge *br, + const struct ovsrec_port *port, + const struct ovsrec_interface *iface) +{ + if (port->n_interfaces == 1) { + del_port(br, port); + } else { + struct ovsrec_interface **ifaces; + size_t i, n; + + ifaces = xmalloc(sizeof *port->interfaces * port->n_interfaces); + for (i = n = 0; i < port->n_interfaces; i++) { + if (port->interfaces[i] != iface) { + ifaces[n++] = port->interfaces[i]; + } + } + ovsrec_port_set_interfaces(port, ifaces, n); + free(ifaces); + ovsrec_interface_delete(iface); + } +} + +/* Find and return a port within 'br' named 'port_name'. */ +static const struct ovsrec_port * +find_port(const struct ovsrec_bridge *br, const char *port_name) +{ + size_t i; for (i = 0; i < br->n_ports; i++) { struct ovsrec_port *port = br->ports[i]; if (!strcmp(port_name, port->name)) { - port_rec = port; - } - for (j = 0; j < port->n_interfaces; j++) { - struct ovsrec_interface *iface = port->interfaces[j]; - if (!strcmp(port_name, iface->name)) { - ovsrec_interface_delete(iface); - } + return port; } } + return NULL; +} + +/* Find and return an interface within 'br' named 'iface_name'. */ +static const struct ovsrec_interface * +find_interface(const struct ovsrec_bridge *br, const char *iface_name, + struct ovsrec_port **portp) +{ + size_t i; - /* xxx Probably can move this into the "for" loop. */ - if (port_rec) { - struct ovsrec_port **ports; - size_t n; + for (i = 0; i < br->n_ports; i++) { + struct ovsrec_port *port = br->ports[i]; + size_t j; - ports = xmalloc(sizeof *br->ports * br->n_ports); - for (i = n = 0; i < br->n_ports; i++) { - if (br->ports[i] != port_rec) { - ports[n++] = br->ports[i]; + for (j = 0; j < port->n_interfaces; j++) { + struct ovsrec_interface *iface = port->interfaces[j]; + if (!strcmp(iface->name, iface_name)) { + *portp = port; + return iface; } } - ovsrec_bridge_set_ports(br, ports, n); - free(ports); - - ovsrec_port_delete(port_rec); } + + *portp = NULL; + return NULL; } static int @@ -582,7 +574,6 @@ del_bridge(struct ovsdb_idl *idl, struct ovsrec_bridge *br = find_bridge(ovs, br_name); struct ovsrec_bridge **bridges; struct ovsdb_idl_txn *txn; - char *comment; size_t i, n; if (!br) { @@ -592,12 +583,27 @@ del_bridge(struct ovsdb_idl *idl, txn = ovsdb_idl_txn_create(idl); - comment = xasprintf("ovs-brcompatd: delbr %s", br_name); - ovsdb_idl_txn_add_comment(txn, comment); - free(comment); + ovsdb_idl_txn_add_comment(txn, "ovs-brcompatd: delbr %s", br_name); - del_port(br, br_name); + /* Delete everything that the bridge points to, then delete the bridge + * itself. */ + while (br->n_ports > 0) { + del_port(br, br->ports[0]); + } + for (i = 0; i < br->n_mirrors; i++) { + ovsrec_mirror_delete(br->mirrors[i]); + } + if (br->netflow) { + ovsrec_netflow_delete(br->netflow); + } + if (br->sflow) { + ovsrec_sflow_delete(br->sflow); + } + for (i = 0; i < br->n_controller; i++) { + ovsrec_controller_delete(br->controller[i]); + } + /* Remove 'br' from the vswitch's list of bridges. */ bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges); for (i = n = 0; i < ovs->n_bridges; i++) { if (ovs->bridges[i] != br) { @@ -657,7 +663,7 @@ static struct ofpbuf * compose_reply(uint32_t seq, int error) { struct ofpbuf *reply = ofpbuf_new(4096); - nl_msg_put_genlmsghdr(reply, brc_sock, 32, brc_family, NLM_F_REQUEST, + nl_msg_put_genlmsghdr(reply, 32, brc_family, NLM_F_REQUEST, BRC_GENL_C_DP_RESULT, 1); ((struct nlmsghdr *) reply->data)->nlmsg_seq = seq; nl_msg_put_u32(reply, BRC_GENL_A_ERR_CODE, error); @@ -738,19 +744,21 @@ handle_port_cmd(struct ovsdb_idl *idl, } else { do { struct ovsdb_idl_txn *txn = ovsdb_idl_txn_create(idl); - char *comment; if (add) { - comment = xasprintf("ovs-brcompatd: add-if %s", port_name); + ovsdb_idl_txn_add_comment(txn, "ovs-brcompatd: add-if %s", + port_name); add_port(ovs, br, port_name); } else { - comment = xasprintf("ovs-brcompatd: del-if %s", port_name); - del_port(br, port_name); + const struct ovsrec_port *port = find_port(br, port_name); + if (port) { + ovsdb_idl_txn_add_comment(txn, + "ovs-brcompatd: del-if %s", + port_name); + del_port(br, port); + } } - ovsdb_idl_txn_add_comment(txn, comment); - free(comment); - error = commit_txn(txn, true); VLOG_INFO_RL(&rl, "%s %s %s: %s", cmd_name, br_name, port_name, strerror(error)); @@ -1199,8 +1207,9 @@ rtnl_recv_update(struct ovsdb_idl *idl, if (!netdev_exists(port_name)) { /* Network device is really gone. */ struct ovsdb_idl_txn *txn; + const struct ovsrec_interface *iface; + struct ovsrec_port *port; struct ovsrec_bridge *br; - char *comment; VLOG_INFO("network device %s destroyed, " "removing from bridge %s", port_name, br_name); @@ -1215,12 +1224,14 @@ rtnl_recv_update(struct ovsdb_idl *idl, txn = ovsdb_idl_txn_create(idl); - comment = xasprintf("ovs-brcompatd: destroy port %s", - port_name); - ovsdb_idl_txn_add_comment(txn, comment); - free(comment); + iface = find_interface(br, port_name, &port); + if (iface) { + del_interface(br, port, iface); + ovsdb_idl_txn_add_comment(txn, + "ovs-brcompatd: destroy port %s", + port_name); + } - del_port(br, port_name); commit_txn(txn, false); } else { /* A network device by that name exists even though the kernel @@ -1344,10 +1355,6 @@ main(int argc, char *argv[]) */ if (ovs && prune_timeout) { rtnl_recv_update(idl, ovs); -#if 0 - prune_ports(); -#endif - nl_sock_wait(rtnl_sock, POLLIN); poll_timer_wait(prune_timeout); }