X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=vswitchd%2Fovs-brcompatd.c;h=973b098b2f1e43303964d28f146e5be0f18f9450;hb=b2fda3effc787f265b5ad5dfa967ac00627bd075;hp=fe953f436a29ab31354e7f42c601836abc43f692;hpb=05edc34ca119606f349c6557f2fbe682861ab3d8;p=sliver-openvswitch.git diff --git a/vswitchd/ovs-brcompatd.c b/vswitchd/ovs-brcompatd.c index fe953f436..973b098b2 100644 --- a/vswitchd/ovs-brcompatd.c +++ b/vswitchd/ovs-brcompatd.c @@ -51,7 +51,7 @@ #include "poll-loop.h" #include "process.h" #include "signals.h" -#include "svec.h" +#include "sset.h" #include "timeval.h" #include "unixctl.h" #include "util.h" @@ -230,17 +230,14 @@ execute_appctl_command(const char *unixctl_command, char **output) } static void -do_get_bridge_parts(const struct ovsrec_bridge *br, struct svec *parts, +do_get_bridge_parts(const struct ovsrec_bridge *br, struct sset *parts, int vlan, bool break_down_bonds) { - struct svec ports; size_t i, j; - svec_init(&ports); for (i = 0; i < br->n_ports; i++) { const struct ovsrec_port *port = br->ports[i]; - svec_add(&ports, port->name); if (vlan >= 0) { int port_vlan = port->n_tag ? *port->tag : 0; if (vlan != port_vlan) { @@ -250,13 +247,12 @@ do_get_bridge_parts(const struct ovsrec_bridge *br, struct svec *parts, if (break_down_bonds) { for (j = 0; j < port->n_interfaces; j++) { const struct ovsrec_interface *iface = port->interfaces[j]; - svec_add(parts, iface->name); + sset_add(parts, iface->name); } } else { - svec_add(parts, port->name); + sset_add(parts, port->name); } } - svec_destroy(&ports); } /* Add all the interfaces for 'bridge' to 'ifaces', breaking bonded interfaces @@ -267,7 +263,7 @@ do_get_bridge_parts(const struct ovsrec_bridge *br, struct svec *parts, * reported. If 'vlan' > 0, only interfaces with implicit VLAN 'vlan' are * reported. */ static void -get_bridge_ifaces(const struct ovsrec_bridge *br, struct svec *ifaces, +get_bridge_ifaces(const struct ovsrec_bridge *br, struct sset *ifaces, int vlan) { do_get_bridge_parts(br, ifaces, vlan, true); @@ -280,7 +276,7 @@ get_bridge_ifaces(const struct ovsrec_bridge *br, struct svec *ifaces, * only trunk ports or ports with implicit VLAN 0 are reported. If 'vlan' > 0, * only port with implicit VLAN 'vlan' are reported. */ static void -get_bridge_ports(const struct ovsrec_bridge *br, struct svec *ports, +get_bridge_ports(const struct ovsrec_bridge *br, struct sset *ports, int vlan) { do_get_bridge_parts(br, ports, vlan, false); @@ -497,14 +493,6 @@ del_port(const struct ovsrec_bridge *br, const struct ovsrec_port *port) } 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 @@ -530,7 +518,6 @@ del_interface(const struct ovsrec_bridge *br, } ovsrec_port_set_interfaces(port, ifaces, n); free(ifaces); - ovsrec_interface_delete(iface); } } @@ -591,24 +578,6 @@ del_bridge(struct ovsdb_idl *idl, ovsdb_idl_txn_add_comment(txn, "ovs-brcompatd: delbr %s", 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++) { @@ -619,9 +588,6 @@ del_bridge(struct ovsdb_idl *idl, ovsrec_open_vswitch_set_bridges(ovs, bridges, n); free(bridges); - /* Delete the bridge itself. */ - ovsrec_bridge_delete(br); - return commit_txn(txn, true); } @@ -847,9 +813,10 @@ handle_fdb_query_cmd(const struct ovsrec_open_vswitch *ovs, const char *linux_name; /* Name used by brctl. */ const struct ovsrec_bridge *ovs_bridge; /* Bridge used by ovs-vswitchd. */ int br_vlan; /* VLAN tag. */ - struct svec ifaces; + struct sset ifaces; struct ofpbuf query_data; + const char *iface_name; struct ofpbuf *reply; char *unixctl_command; uint64_t count, skip; @@ -883,12 +850,11 @@ handle_fdb_query_cmd(const struct ovsrec_open_vswitch *ovs, /* Fetch the MAC address for each interface on the bridge, so that we can * fill in the is_local field in the response. */ - svec_init(&ifaces); + sset_init(&ifaces); get_bridge_ifaces(ovs_bridge, &ifaces, br_vlan); - local_macs = xmalloc(ifaces.n * sizeof *local_macs); + local_macs = xmalloc(sset_count(&ifaces) * sizeof *local_macs); n_local_macs = 0; - for (i = 0; i < ifaces.n; i++) { - const char *iface_name = ifaces.names[i]; + SSET_FOR_EACH (iface_name, &ifaces) { struct mac *mac = &local_macs[n_local_macs]; struct netdev *netdev; @@ -900,7 +866,7 @@ handle_fdb_query_cmd(const struct ovsrec_open_vswitch *ovs, netdev_close(netdev); } } - svec_destroy(&ifaces); + sset_destroy(&ifaces); /* Parse the response from ovs-appctl and convert it to binary format to * pass back to the kernel. */ @@ -971,22 +937,17 @@ handle_fdb_query_cmd(const struct ovsrec_open_vswitch *ovs, } static void -send_ifindex_reply(uint32_t seq, struct svec *ifaces) +send_ifindex_reply(uint32_t seq, struct sset *ifaces) { struct ofpbuf *reply; const char *iface; size_t n_indices; int *indices; - size_t i; - - /* Make sure that any given interface only occurs once. This shouldn't - * happen, but who knows what people put into their configuration files. */ - svec_sort_unique(ifaces); /* Convert 'ifaces' into ifindexes. */ n_indices = 0; - indices = xmalloc(ifaces->n * sizeof *indices); - SVEC_FOR_EACH (i, iface, ifaces) { + indices = xmalloc(sset_count(ifaces) * sizeof *indices); + SSET_FOR_EACH (iface, ifaces) { int ifindex = if_nametoindex(iface); if (ifindex) { indices[n_indices++] = ifindex; @@ -1007,7 +968,7 @@ static int handle_get_bridges_cmd(const struct ovsrec_open_vswitch *ovs, struct ofpbuf *buffer) { - struct svec bridges; + struct sset bridges; size_t i, j; uint32_t seq; @@ -1024,22 +985,22 @@ handle_get_bridges_cmd(const struct ovsrec_open_vswitch *ovs, } /* Get all the real bridges and all the fake ones. */ - svec_init(&bridges); + sset_init(&bridges); for (i = 0; i < ovs->n_bridges; i++) { const struct ovsrec_bridge *br = ovs->bridges[i]; - svec_add(&bridges, br->name); + sset_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); + sset_add(&bridges, port->name); } } } send_ifindex_reply(seq, &bridges); - svec_destroy(&bridges); + sset_destroy(&bridges); return 0; } @@ -1054,7 +1015,7 @@ handle_get_ports_cmd(const struct ovsrec_open_vswitch *ovs, const struct ovsrec_bridge *ovs_bridge; int br_vlan; - struct svec ports; + struct sset ports; int error; @@ -1071,36 +1032,54 @@ handle_get_ports_cmd(const struct ovsrec_open_vswitch *ovs, return error; } - svec_init(&ports); + sset_init(&ports); get_bridge_ports(ovs_bridge, &ports, br_vlan); - svec_sort(&ports); - svec_del(&ports, linux_name); + sset_find_and_delete(&ports, linux_name); send_ifindex_reply(seq, &ports); /* XXX bonds won't show up */ - svec_destroy(&ports); + sset_destroy(&ports); return 0; } +static struct ofpbuf * +brc_recv_update__(void) +{ + for (;;) { + struct ofpbuf *buffer; + int retval; + + retval = nl_sock_recv(brc_sock, &buffer, false); + switch (retval) { + case 0: + if (nl_msg_nlmsgerr(buffer, NULL) + || nl_msg_nlmsghdr(buffer)->nlmsg_type == NLMSG_DONE) { + break; + } + return buffer; + + case ENOBUFS: + break; + + case EAGAIN: + return NULL; + + default: + VLOG_WARN_RL(&rl, "brc_recv_update: %s", strerror(retval)); + return NULL; + } + ofpbuf_delete(buffer); + } +} + static void brc_recv_update(struct ovsdb_idl *idl) { - int retval; struct ofpbuf *buffer; struct genlmsghdr *genlmsghdr; const struct ovsrec_open_vswitch *ovs; - buffer = NULL; - do { - ofpbuf_delete(buffer); - retval = nl_sock_recv(brc_sock, &buffer, false); - } while (retval == ENOBUFS - || (!retval - && (nl_msg_nlmsgerr(buffer, NULL) - || nl_msg_nlmsghdr(buffer)->nlmsg_type == NLMSG_DONE))); - if (retval) { - if (retval != EAGAIN) { - VLOG_WARN_RL(&rl, "brc_recv_update: %s", strerror(retval)); - } + buffer = brc_recv_update__(); + if (!buffer) { return; } @@ -1310,7 +1289,6 @@ main(int argc, char *argv[]) process_init(); ovsrec_init(); - die_if_already_running(); daemonize_start(); retval = unixctl_server_create(NULL, &unixctl); @@ -1319,8 +1297,8 @@ main(int argc, char *argv[]) } if (brc_open(&brc_sock)) { - ovs_fatal(0, "could not open brcompat socket. Check " - "\"brcompat\" kernel module."); + VLOG_FATAL("could not open brcompat socket. Check " + "\"brcompat\" kernel module."); } if (prune_timeout) { @@ -1328,12 +1306,14 @@ main(int argc, char *argv[]) error = nl_sock_create(NETLINK_ROUTE, &rtnl_sock); if (error) { - ovs_fatal(error, "could not create rtnetlink socket"); + VLOG_FATAL("could not create rtnetlink socket (%s)", + strerror(error)); } error = nl_sock_join_mcgroup(rtnl_sock, RTNLGRP_LINK); if (error) { - ovs_fatal(error, "could not join RTNLGRP_LINK multicast group"); + VLOG_FATAL("could not join RTNLGRP_LINK multicast group (%s)", + strerror(error)); } } @@ -1399,11 +1379,11 @@ validate_appctl_command(void) } else if (p[1] == 's') { n++; } else { - ovs_fatal(0, "only '%%s' and '%%%%' allowed in --appctl-command"); + VLOG_FATAL("only '%%s' and '%%%%' allowed in --appctl-command"); } } if (n != 1) { - ovs_fatal(0, "'%%s' must appear exactly once in --appctl-command"); + VLOG_FATAL("'%%s' must appear exactly once in --appctl-command"); } } @@ -1418,14 +1398,14 @@ parse_options(int argc, char *argv[]) DAEMON_OPTION_ENUMS }; static struct option long_options[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"prune-timeout", required_argument, 0, OPT_PRUNE_TIMEOUT}, - {"appctl-command", required_argument, 0, OPT_APPCTL_COMMAND}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"prune-timeout", required_argument, NULL, OPT_PRUNE_TIMEOUT}, + {"appctl-command", required_argument, NULL, OPT_APPCTL_COMMAND}, DAEMON_LONG_OPTIONS, VLOG_LONG_OPTIONS, LEAK_CHECKER_LONG_OPTIONS, - {0, 0, 0, 0}, + {NULL, 0, NULL, 0}, }; char *short_options = long_options_to_short_options(long_options); @@ -1474,8 +1454,8 @@ parse_options(int argc, char *argv[]) argv += optind; if (argc != 1) { - ovs_fatal(0, "database socket is non-option argument; " - "use --help for usage"); + VLOG_FATAL("database socket is non-option argument; " + "use --help for usage"); } return argv[0];