LCOV - code coverage report
Current view: top level - utilities - ovs-vsctl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 909 1183 76.8 %
Date: 2016-09-14 01:02:56 Functions: 79 95 83.2 %
Branches: 384 620 61.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : 
      19                 :            : #include <ctype.h>
      20                 :            : #include <errno.h>
      21                 :            : #include <float.h>
      22                 :            : #include <getopt.h>
      23                 :            : #include <inttypes.h>
      24                 :            : #include <signal.h>
      25                 :            : #include <stdarg.h>
      26                 :            : #include <stdlib.h>
      27                 :            : #include <string.h>
      28                 :            : #include <unistd.h>
      29                 :            : 
      30                 :            : #include "db-ctl-base.h"
      31                 :            : 
      32                 :            : #include "command-line.h"
      33                 :            : #include "compiler.h"
      34                 :            : #include "openvswitch/dynamic-string.h"
      35                 :            : #include "fatal-signal.h"
      36                 :            : #include "hash.h"
      37                 :            : #include "openvswitch/json.h"
      38                 :            : #include "ovsdb-data.h"
      39                 :            : #include "ovsdb-idl.h"
      40                 :            : #include "poll-loop.h"
      41                 :            : #include "process.h"
      42                 :            : #include "stream.h"
      43                 :            : #include "stream-ssl.h"
      44                 :            : #include "smap.h"
      45                 :            : #include "sset.h"
      46                 :            : #include "svec.h"
      47                 :            : #include "lib/vswitch-idl.h"
      48                 :            : #include "table.h"
      49                 :            : #include "timeval.h"
      50                 :            : #include "util.h"
      51                 :            : #include "openvswitch/vconn.h"
      52                 :            : #include "openvswitch/vlog.h"
      53                 :            : 
      54                 :       9300 : VLOG_DEFINE_THIS_MODULE(vsctl);
      55                 :            : 
      56                 :            : struct vsctl_context;
      57                 :            : 
      58                 :            : /* --db: The database server to contact. */
      59                 :            : static const char *db;
      60                 :            : 
      61                 :            : /* --oneline: Write each command's output as a single line? */
      62                 :            : static bool oneline;
      63                 :            : 
      64                 :            : /* --dry-run: Do not commit any changes. */
      65                 :            : static bool dry_run;
      66                 :            : 
      67                 :            : /* --no-wait: Wait for ovs-vswitchd to reload its configuration? */
      68                 :            : static bool wait_for_reload = true;
      69                 :            : 
      70                 :            : /* --timeout: Time to wait for a connection to 'db'. */
      71                 :            : static int timeout;
      72                 :            : 
      73                 :            : /* --retry: If true, ovs-vsctl will retry connecting to the database forever.
      74                 :            :  * If false and --db says to use an active connection method (e.g. "unix:",
      75                 :            :  * "tcp:", "ssl:"), then ovs-vsctl will try to connect once and exit with an
      76                 :            :  * error if the database server cannot be contacted (e.g. ovsdb-server is not
      77                 :            :  * running).
      78                 :            :  *
      79                 :            :  * Regardless of this setting, --timeout always limits how long ovs-vsctl will
      80                 :            :  * wait. */
      81                 :            : static bool retry;
      82                 :            : 
      83                 :            : /* Format for table output. */
      84                 :            : static struct table_style table_style = TABLE_STYLE_DEFAULT;
      85                 :            : 
      86                 :            : static void vsctl_cmd_init(void);
      87                 :            : 
      88                 :            : /* The IDL we're using and the current transaction, if any.
      89                 :            :  * This is for use by vsctl_exit() only, to allow it to clean up.
      90                 :            :  * Other code should use its context arguments. */
      91                 :            : static struct ovsdb_idl *the_idl;
      92                 :            : static struct ovsdb_idl_txn *the_idl_txn;
      93                 :            : OVS_NO_RETURN static void vsctl_exit(int status);
      94                 :            : 
      95                 :            : OVS_NO_RETURN static void usage(void);
      96                 :            : static void parse_options(int argc, char *argv[], struct shash *local_options);
      97                 :            : static void run_prerequisites(struct ctl_command[], size_t n_commands,
      98                 :            :                               struct ovsdb_idl *);
      99                 :            : static void do_vsctl(const char *args, struct ctl_command *, size_t n,
     100                 :            :                      struct ovsdb_idl *);
     101                 :            : 
     102                 :            : /* post_db_reload_check frame work is to allow ovs-vsctl to do additional
     103                 :            :  * checks after OVSDB transactions are successfully recorded and reload by
     104                 :            :  * ovs-vswitchd.
     105                 :            :  *
     106                 :            :  * For example, When a new interface is added to OVSDB, ovs-vswitchd will
     107                 :            :  * either store a positive values on successful implementing the new
     108                 :            :  * interface, or -1 on failure.
     109                 :            :  *
     110                 :            :  * Unless --no-wait command line option is specified,
     111                 :            :  * post_db_reload_do_checks() is called right after any configuration
     112                 :            :  * changes is picked up (i.e. reload) by ovs-vswitchd. Any error detected
     113                 :            :  * post OVSDB reload is reported as ovs-vsctl errors. OVS-vswitchd logs
     114                 :            :  * more detailed messages about those errors.
     115                 :            :  *
     116                 :            :  * Current implementation only check for Post OVSDB reload failures on new
     117                 :            :  * interface additions with 'add-br' and 'add-port' commands.
     118                 :            :  *
     119                 :            :  * post_db_reload_expect_iface()
     120                 :            :  *
     121                 :            :  * keep track of interfaces to be checked post OVSDB reload. */
     122                 :            : static void post_db_reload_check_init(void);
     123                 :            : static void post_db_reload_do_checks(const struct vsctl_context *);
     124                 :            : static void post_db_reload_expect_iface(const struct ovsrec_interface *);
     125                 :            : 
     126                 :            : static struct uuid *neoteric_ifaces;
     127                 :            : static size_t n_neoteric_ifaces;
     128                 :            : static size_t allocated_neoteric_ifaces;
     129                 :            : 
     130                 :            : int
     131                 :       4650 : main(int argc, char *argv[])
     132                 :            : {
     133                 :            :     struct ovsdb_idl *idl;
     134                 :            :     struct ctl_command *commands;
     135                 :            :     struct shash local_options;
     136                 :            :     unsigned int seqno;
     137                 :            :     size_t n_commands;
     138                 :            :     char *args;
     139                 :            : 
     140                 :       4650 :     set_program_name(argv[0]);
     141                 :       4650 :     fatal_ignore_sigpipe();
     142                 :       4650 :     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
     143                 :       4650 :     vlog_set_levels_from_string_assert("reconnect:warn");
     144                 :       4650 :     ovsrec_init();
     145                 :            : 
     146                 :       4650 :     vsctl_cmd_init();
     147                 :            : 
     148                 :            :     /* Log our arguments.  This is often valuable for debugging systems. */
     149                 :       4650 :     args = process_escape_args(argv);
     150 [ +  + ][ +  + ]:       4650 :     VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG, "Called as %s", args);
     151                 :            : 
     152                 :            :     /* Parse command line. */
     153                 :       4650 :     shash_init(&local_options);
     154                 :       4650 :     parse_options(argc, argv, &local_options);
     155                 :       4533 :     commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
     156                 :            :                                   &n_commands);
     157                 :            : 
     158         [ +  + ]:       4530 :     if (timeout) {
     159                 :        476 :         time_alarm(timeout);
     160                 :            :     }
     161                 :            : 
     162                 :            :     /* Initialize IDL. */
     163                 :       4530 :     idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false, retry);
     164                 :       4530 :     run_prerequisites(commands, n_commands, idl);
     165                 :            : 
     166                 :            :     /* Execute the commands.
     167                 :            :      *
     168                 :            :      * 'seqno' is the database sequence number for which we last tried to
     169                 :            :      * execute our transaction.  There's no point in trying to commit more than
     170                 :            :      * once for any given sequence number, because if the transaction fails
     171                 :            :      * it's because the database changed and we need to obtain an up-to-date
     172                 :            :      * view of the database before we try the transaction again. */
     173                 :       4524 :     seqno = ovsdb_idl_get_seqno(idl);
     174                 :            :     for (;;) {
     175                 :      11653 :         ovsdb_idl_run(idl);
     176         [ +  + ]:      11653 :         if (!ovsdb_idl_is_alive(idl)) {
     177                 :          5 :             int retval = ovsdb_idl_get_last_error(idl);
     178                 :          5 :             ctl_fatal("%s: database connection failed (%s)",
     179                 :            :                         db, ovs_retval_to_string(retval));
     180                 :            :         }
     181                 :            : 
     182         [ +  + ]:      11648 :         if (seqno != ovsdb_idl_get_seqno(idl)) {
     183                 :       4526 :             seqno = ovsdb_idl_get_seqno(idl);
     184                 :       4526 :             do_vsctl(args, commands, n_commands, idl);
     185                 :            :         }
     186                 :            : 
     187         [ +  - ]:       7129 :         if (seqno == ovsdb_idl_get_seqno(idl)) {
     188                 :       7129 :             ovsdb_idl_wait(idl);
     189                 :       7129 :             poll_block();
     190                 :            :         }
     191                 :       7129 :     }
     192                 :            : }
     193                 :            : 
     194                 :            : static void
     195                 :       4650 : parse_options(int argc, char *argv[], struct shash *local_options)
     196                 :            : {
     197                 :            :     enum {
     198                 :            :         OPT_DB = UCHAR_MAX + 1,
     199                 :            :         OPT_ONELINE,
     200                 :            :         OPT_NO_SYSLOG,
     201                 :            :         OPT_NO_WAIT,
     202                 :            :         OPT_DRY_RUN,
     203                 :            :         OPT_BOOTSTRAP_CA_CERT,
     204                 :            :         OPT_PEER_CA_CERT,
     205                 :            :         OPT_LOCAL,
     206                 :            :         OPT_RETRY,
     207                 :            :         OPT_COMMANDS,
     208                 :            :         OPT_OPTIONS,
     209                 :            :         VLOG_OPTION_ENUMS,
     210                 :            :         TABLE_OPTION_ENUMS
     211                 :            :     };
     212                 :            :     static const struct option global_long_options[] = {
     213                 :            :         {"db", required_argument, NULL, OPT_DB},
     214                 :            :         {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
     215                 :            :         {"no-wait", no_argument, NULL, OPT_NO_WAIT},
     216                 :            :         {"dry-run", no_argument, NULL, OPT_DRY_RUN},
     217                 :            :         {"oneline", no_argument, NULL, OPT_ONELINE},
     218                 :            :         {"timeout", required_argument, NULL, 't'},
     219                 :            :         {"retry", no_argument, NULL, OPT_RETRY},
     220                 :            :         {"help", no_argument, NULL, 'h'},
     221                 :            :         {"commands", no_argument, NULL, OPT_COMMANDS},
     222                 :            :         {"options", no_argument, NULL, OPT_OPTIONS},
     223                 :            :         {"version", no_argument, NULL, 'V'},
     224                 :            :         VLOG_LONG_OPTIONS,
     225                 :            :         TABLE_LONG_OPTIONS,
     226                 :            :         STREAM_SSL_LONG_OPTIONS,
     227                 :            :         {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
     228                 :            :         {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
     229                 :            :         {NULL, 0, NULL, 0},
     230                 :            :     };
     231                 :       4650 :     const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
     232                 :            :     char *tmp, *short_options;
     233                 :            : 
     234                 :            :     struct option *options;
     235                 :            :     size_t allocated_options;
     236                 :            :     size_t n_options;
     237                 :            :     size_t i;
     238                 :            : 
     239                 :       4650 :     tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
     240                 :       4650 :     short_options = xasprintf("+%s", tmp);
     241                 :       4650 :     free(tmp);
     242                 :            : 
     243                 :            :     /* We want to parse both global and command-specific options here, but
     244                 :            :      * getopt_long() isn't too convenient for the job.  We copy our global
     245                 :            :      * options into a dynamic array, then append all of the command-specific
     246                 :            :      * options. */
     247                 :       4650 :     options = xmemdup(global_long_options, sizeof global_long_options);
     248                 :       4650 :     allocated_options = ARRAY_SIZE(global_long_options);
     249                 :       4650 :     n_options = n_global_long_options;
     250                 :       4650 :     ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
     251                 :       4650 :     table_style.format = TF_LIST;
     252                 :            : 
     253                 :            :     for (;;) {
     254                 :            :         int idx;
     255                 :            :         int c;
     256                 :            : 
     257                 :       8832 :         c = getopt_long(argc, argv, short_options, options, &idx);
     258         [ +  + ]:       8832 :         if (c == -1) {
     259                 :       4533 :             break;
     260                 :            :         }
     261                 :            : 
     262   [ +  +  -  +  :       4299 :         switch (c) {
          -  +  -  +  +  
          +  +  -  +  -  
          -  -  +  +  +  
          -  +  +  +  -  
             -  +  -  - ]
     263                 :            :         case OPT_DB:
     264                 :        730 :             db = optarg;
     265                 :        730 :             break;
     266                 :            : 
     267                 :            :         case OPT_ONELINE:
     268                 :        141 :             oneline = true;
     269                 :        141 :             break;
     270                 :            : 
     271                 :            :         case OPT_NO_SYSLOG:
     272                 :          0 :             vlog_set_levels(&this_module, VLF_SYSLOG, VLL_WARN);
     273                 :          0 :             break;
     274                 :            : 
     275                 :            :         case OPT_NO_WAIT:
     276                 :       1393 :             wait_for_reload = false;
     277                 :       1393 :             break;
     278                 :            : 
     279                 :            :         case OPT_DRY_RUN:
     280                 :          0 :             dry_run = true;
     281                 :          0 :             break;
     282                 :            : 
     283                 :            :         case OPT_LOCAL:
     284         [ -  + ]:        171 :             if (shash_find(local_options, options[idx].name)) {
     285                 :          0 :                 ctl_fatal("'%s' option specified multiple times",
     286                 :          0 :                             options[idx].name);
     287                 :            :             }
     288                 :        171 :             shash_add_nocopy(local_options,
     289                 :        171 :                              xasprintf("--%s", options[idx].name),
     290                 :        171 :                              nullable_xstrdup(optarg));
     291                 :        171 :             break;
     292                 :            : 
     293                 :            :         case 'h':
     294                 :          0 :             usage();
     295                 :            : 
     296                 :            :         case OPT_COMMANDS:
     297                 :         56 :             ctl_print_commands();
     298                 :            : 
     299                 :            :         case OPT_OPTIONS:
     300                 :         54 :             ctl_print_options(global_long_options);
     301                 :            : 
     302                 :            :         case 'V':
     303                 :          7 :             ovs_print_version(0, 0);
     304                 :          7 :             printf("DB Schema %s\n", ovsrec_get_db_version());
     305                 :          7 :             exit(EXIT_SUCCESS);
     306                 :            : 
     307                 :            :         case 't':
     308                 :        476 :             timeout = strtoul(optarg, NULL, 10);
     309         [ -  + ]:        476 :             if (timeout < 0) {
     310                 :          0 :                 ctl_fatal("value %s on -t or --timeout is invalid",
     311                 :            :                             optarg);
     312                 :            :             }
     313                 :        476 :             break;
     314                 :            : 
     315                 :            :         case OPT_RETRY:
     316                 :          0 :             retry = true;
     317                 :          0 :             break;
     318                 :            : 
     319                 :       1014 :         VLOG_OPTION_HANDLERS
     320                 :        239 :         TABLE_OPTION_HANDLERS(&table_style)
     321                 :            : 
     322                 :         12 :         STREAM_SSL_OPTION_HANDLERS
     323                 :            : 
     324                 :            :         case OPT_PEER_CA_CERT:
     325                 :          0 :             stream_ssl_set_peer_ca_cert_file(optarg);
     326                 :          0 :             break;
     327                 :            : 
     328                 :            :         case OPT_BOOTSTRAP_CA_CERT:
     329                 :          6 :             stream_ssl_set_ca_cert_file(optarg, true);
     330                 :          6 :             break;
     331                 :            : 
     332                 :            :         case '?':
     333                 :          0 :             exit(EXIT_FAILURE);
     334                 :            : 
     335                 :            :         default:
     336                 :          0 :             abort();
     337                 :            :         }
     338                 :       4182 :     }
     339                 :       4533 :     free(short_options);
     340                 :            : 
     341         [ +  + ]:       4533 :     if (!db) {
     342                 :       3803 :         db = ctl_default_db();
     343                 :            :     }
     344                 :            : 
     345         [ +  + ]:      49863 :     for (i = n_global_long_options; options[i].name; i++) {
     346                 :      45330 :         free(CONST_CAST(char *, options[i].name));
     347                 :            :     }
     348                 :       4533 :     free(options);
     349                 :       4533 : }
     350                 :            : 
     351                 :            : static void
     352                 :          0 : usage(void)
     353                 :            : {
     354                 :          0 :     printf("\
     355                 :            : %s: ovs-vswitchd management utility\n\
     356                 :            : usage: %s [OPTIONS] COMMAND [ARG...]\n\
     357                 :            : \n\
     358                 :            : Open vSwitch commands:\n\
     359                 :            :   init                        initialize database, if not yet initialized\n\
     360                 :            :   show                        print overview of database contents\n\
     361                 :            :   emer-reset                  reset configuration to clean state\n\
     362                 :            : \n\
     363                 :            : Bridge commands:\n\
     364                 :            :   add-br BRIDGE               create a new bridge named BRIDGE\n\
     365                 :            :   add-br BRIDGE PARENT VLAN   create new fake BRIDGE in PARENT on VLAN\n\
     366                 :            :   del-br BRIDGE               delete BRIDGE and all of its ports\n\
     367                 :            :   list-br                     print the names of all the bridges\n\
     368                 :            :   br-exists BRIDGE            exit 2 if BRIDGE does not exist\n\
     369                 :            :   br-to-vlan BRIDGE           print the VLAN which BRIDGE is on\n\
     370                 :            :   br-to-parent BRIDGE         print the parent of BRIDGE\n\
     371                 :            :   br-set-external-id BRIDGE KEY VALUE  set KEY on BRIDGE to VALUE\n\
     372                 :            :   br-set-external-id BRIDGE KEY  unset KEY on BRIDGE\n\
     373                 :            :   br-get-external-id BRIDGE KEY  print value of KEY on BRIDGE\n\
     374                 :            :   br-get-external-id BRIDGE  list key-value pairs on BRIDGE\n\
     375                 :            : \n\
     376                 :            : Port commands (a bond is considered to be a single port):\n\
     377                 :            :   list-ports BRIDGE           print the names of all the ports on BRIDGE\n\
     378                 :            :   add-port BRIDGE PORT        add network device PORT to BRIDGE\n\
     379                 :            :   add-bond BRIDGE PORT IFACE...  add bonded port PORT in BRIDGE from IFACES\n\
     380                 :            :   del-port [BRIDGE] PORT      delete PORT (which may be bonded) from BRIDGE\n\
     381                 :            :   port-to-br PORT             print name of bridge that contains PORT\n\
     382                 :            : \n\
     383                 :            : Interface commands (a bond consists of multiple interfaces):\n\
     384                 :            :   list-ifaces BRIDGE          print the names of all interfaces on BRIDGE\n\
     385                 :            :   iface-to-br IFACE           print name of bridge that contains IFACE\n\
     386                 :            : \n\
     387                 :            : Controller commands:\n\
     388                 :            :   get-controller BRIDGE      print the controllers for BRIDGE\n\
     389                 :            :   del-controller BRIDGE      delete the controllers for BRIDGE\n\
     390                 :            :   set-controller BRIDGE TARGET...  set the controllers for BRIDGE\n\
     391                 :            :   get-fail-mode BRIDGE       print the fail-mode for BRIDGE\n\
     392                 :            :   del-fail-mode BRIDGE       delete the fail-mode for BRIDGE\n\
     393                 :            :   set-fail-mode BRIDGE MODE  set the fail-mode for BRIDGE to MODE\n\
     394                 :            : \n\
     395                 :            : Manager commands:\n\
     396                 :            :   get-manager                print the managers\n\
     397                 :            :   del-manager                delete the managers\n\
     398                 :            :   set-manager TARGET...      set the list of managers to TARGET...\n\
     399                 :            : \n\
     400                 :            : SSL commands:\n\
     401                 :            :   get-ssl                     print the SSL configuration\n\
     402                 :            :   del-ssl                     delete the SSL configuration\n\
     403                 :            :   set-ssl PRIV-KEY CERT CA-CERT  set the SSL configuration\n\
     404                 :            : \n\
     405                 :            : Auto Attach commands:\n\
     406                 :            :   add-aa-mapping BRIDGE I-SID VLAN   add Auto Attach mapping to BRIDGE\n\
     407                 :            :   del-aa-mapping BRIDGE I-SID VLAN   delete Auto Attach mapping VLAN from BRIDGE\n\
     408                 :            :   get-aa-mapping BRIDGE              get Auto Attach mappings from BRIDGE\n\
     409                 :            : \n\
     410                 :            : Switch commands:\n\
     411                 :            :   emer-reset                  reset switch to known good state\n\
     412                 :            : \n\
     413                 :            : %s\
     414                 :            : \n\
     415                 :            : Options:\n\
     416                 :            :   --db=DATABASE               connect to DATABASE\n\
     417                 :            :                               (default: %s)\n\
     418                 :            :   --no-wait                   do not wait for ovs-vswitchd to reconfigure\n\
     419                 :            :   --retry                     keep trying to connect to server forever\n\
     420                 :            :   -t, --timeout=SECS          wait at most SECS seconds for ovs-vswitchd\n\
     421                 :            :   --dry-run                   do not commit changes to database\n\
     422                 :            :   --oneline                   print exactly one line of output per command\n",
     423                 :            :            program_name, program_name, ctl_get_db_cmd_usage(), ctl_default_db());
     424                 :          0 :     vlog_usage();
     425                 :          0 :     printf("\
     426                 :            :   --no-syslog             equivalent to --verbose=vsctl:syslog:warn\n");
     427                 :          0 :     stream_usage("database", true, true, false);
     428                 :          0 :     printf("\n\
     429                 :            : Other options:\n\
     430                 :            :   -h, --help                  display this help message\n\
     431                 :            :   -V, --version               display version information\n");
     432                 :          0 :     exit(EXIT_SUCCESS);
     433                 :            : }
     434                 :            : 
     435                 :            : 
     436                 :            : /* ovs-vsctl specific context.  Inherits the 'struct ctl_context' as base. */
     437                 :            : struct vsctl_context {
     438                 :            :     struct ctl_context base;
     439                 :            : 
     440                 :            :     /* Modifiable state. */
     441                 :            :     const struct ovsrec_open_vswitch *ovs;
     442                 :            :     bool verified_ports;
     443                 :            : 
     444                 :            :     /* A cache of the contents of the database.
     445                 :            :      *
     446                 :            :      * A command that needs to use any of this information must first call
     447                 :            :      * vsctl_context_populate_cache().  A command that changes anything that
     448                 :            :      * could invalidate the cache must either call
     449                 :            :      * vsctl_context_invalidate_cache() or manually update the cache to
     450                 :            :      * maintain its correctness. */
     451                 :            :     bool cache_valid;
     452                 :            :     struct shash bridges;   /* Maps from bridge name to struct vsctl_bridge. */
     453                 :            :     struct shash ports;     /* Maps from port name to struct vsctl_port. */
     454                 :            :     struct shash ifaces;    /* Maps from port name to struct vsctl_iface. */
     455                 :            : };
     456                 :            : 
     457                 :            : struct vsctl_bridge {
     458                 :            :     struct ovsrec_bridge *br_cfg;
     459                 :            :     char *name;
     460                 :            :     struct ovs_list ports;      /* Contains "struct vsctl_port"s. */
     461                 :            : 
     462                 :            :     /* VLAN ("fake") bridge support.
     463                 :            :      *
     464                 :            :      * Use 'parent != NULL' to detect a fake bridge, because 'vlan' can be 0
     465                 :            :      * in either case. */
     466                 :            :     struct hmap children;        /* VLAN bridges indexed by 'vlan'. */
     467                 :            :     struct hmap_node children_node; /* Node in parent's 'children' hmap. */
     468                 :            :     struct vsctl_bridge *parent; /* Real bridge, or NULL. */
     469                 :            :     int vlan;                    /* VLAN VID (0...4095), or 0. */
     470                 :            : };
     471                 :            : 
     472                 :            : struct vsctl_port {
     473                 :            :     struct ovs_list ports_node;  /* In struct vsctl_bridge's 'ports' list. */
     474                 :            :     struct ovs_list ifaces;      /* Contains "struct vsctl_iface"s. */
     475                 :            :     struct ovsrec_port *port_cfg;
     476                 :            :     struct vsctl_bridge *bridge;
     477                 :            : };
     478                 :            : 
     479                 :            : struct vsctl_iface {
     480                 :            :     struct ovs_list ifaces_node; /* In struct vsctl_port's 'ifaces' list. */
     481                 :            :     struct ovsrec_interface *iface_cfg;
     482                 :            :     struct vsctl_port *port;
     483                 :            : };
     484                 :            : 
     485                 :            : /* Casts 'base' into 'struct vsctl_context'. */
     486                 :            : static struct vsctl_context *
     487                 :      26564 : vsctl_context_cast(struct ctl_context *base)
     488                 :            : {
     489                 :      26564 :     return CONTAINER_OF(base, struct vsctl_context, base);
     490                 :            : }
     491                 :            : 
     492                 :            : static struct vsctl_bridge *find_vlan_bridge(struct vsctl_bridge *parent,
     493                 :            :                                              int vlan);
     494                 :            : 
     495                 :            : static char *
     496                 :          2 : vsctl_context_to_string(const struct ctl_context *ctx)
     497                 :            : {
     498                 :            :     const struct shash_node *node;
     499                 :            :     struct svec words;
     500                 :            :     char *s;
     501                 :            :     int i;
     502                 :            : 
     503                 :          2 :     svec_init(&words);
     504 [ +  + ][ -  + ]:          4 :     SHASH_FOR_EACH (node, &ctx->options) {
     505                 :          2 :         svec_add(&words, node->name);
     506                 :            :     }
     507         [ +  + ]:         10 :     for (i = 0; i < ctx->argc; i++) {
     508                 :          8 :         svec_add(&words, ctx->argv[i]);
     509                 :            :     }
     510                 :          2 :     svec_terminate(&words);
     511                 :            : 
     512                 :          2 :     s = process_escape_args(words.names);
     513                 :            : 
     514                 :          2 :     svec_destroy(&words);
     515                 :            : 
     516                 :          2 :     return s;
     517                 :            : }
     518                 :            : 
     519                 :            : static void
     520                 :       6691 : verify_ports(struct vsctl_context *vsctl_ctx)
     521                 :            : {
     522         [ +  + ]:       6691 :     if (!vsctl_ctx->verified_ports) {
     523                 :            :         const struct ovsrec_bridge *bridge;
     524                 :            :         const struct ovsrec_port *port;
     525                 :            : 
     526                 :       3844 :         ovsrec_open_vswitch_verify_bridges(vsctl_ctx->ovs);
     527         [ +  + ]:       7582 :         OVSREC_BRIDGE_FOR_EACH (bridge, vsctl_ctx->base.idl) {
     528                 :       3738 :             ovsrec_bridge_verify_ports(bridge);
     529                 :            :         }
     530         [ +  + ]:      94757 :         OVSREC_PORT_FOR_EACH (port, vsctl_ctx->base.idl) {
     531                 :      90913 :             ovsrec_port_verify_interfaces(port);
     532                 :            :         }
     533                 :            : 
     534                 :       3844 :         vsctl_ctx->verified_ports = true;
     535                 :            :     }
     536                 :       6691 : }
     537                 :            : 
     538                 :            : static struct vsctl_bridge *
     539                 :       3338 : add_bridge_to_cache(struct vsctl_context *vsctl_ctx,
     540                 :            :                     struct ovsrec_bridge *br_cfg, const char *name,
     541                 :            :                     struct vsctl_bridge *parent, int vlan)
     542                 :            : {
     543                 :       3338 :     struct vsctl_bridge *br = xmalloc(sizeof *br);
     544                 :       3338 :     br->br_cfg = br_cfg;
     545                 :       3338 :     br->name = xstrdup(name);
     546                 :       3338 :     ovs_list_init(&br->ports);
     547                 :       3338 :     br->parent = parent;
     548                 :       3338 :     br->vlan = vlan;
     549                 :       3338 :     hmap_init(&br->children);
     550         [ +  + ]:       3338 :     if (parent) {
     551                 :        181 :         struct vsctl_bridge *conflict = find_vlan_bridge(parent, vlan);
     552         [ -  + ]:        181 :         if (conflict) {
     553         [ #  # ]:          0 :             VLOG_WARN("%s: bridge has multiple VLAN bridges (%s and %s) "
     554                 :            :                       "for VLAN %d, but only one is allowed",
     555                 :            :                       parent->name, name, conflict->name, vlan);
     556                 :            :         } else {
     557                 :        181 :             hmap_insert(&parent->children, &br->children_node,
     558                 :            :                         hash_int(vlan, 0));
     559                 :            :         }
     560                 :            :     }
     561                 :       3338 :     shash_add(&vsctl_ctx->bridges, br->name, br);
     562                 :       3338 :     return br;
     563                 :            : }
     564                 :            : 
     565                 :            : static void
     566                 :         29 : ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
     567                 :            :                   struct ovsrec_bridge *bridge)
     568                 :            : {
     569                 :            :     struct ovsrec_bridge **bridges;
     570                 :            :     size_t i, n;
     571                 :            : 
     572                 :         29 :     bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
     573         [ +  + ]:         71 :     for (i = n = 0; i < ovs->n_bridges; i++) {
     574         [ +  + ]:         42 :         if (ovs->bridges[i] != bridge) {
     575                 :         13 :             bridges[n++] = ovs->bridges[i];
     576                 :            :         }
     577                 :            :     }
     578                 :         29 :     ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
     579                 :         29 :     free(bridges);
     580                 :         29 : }
     581                 :            : 
     582                 :            : static void
     583                 :         35 : del_cached_bridge(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *br)
     584                 :            : {
     585         [ -  + ]:         35 :     ovs_assert(ovs_list_is_empty(&br->ports));
     586         [ -  + ]:         35 :     ovs_assert(hmap_is_empty(&br->children));
     587         [ +  + ]:         35 :     if (br->parent) {
     588                 :          6 :         hmap_remove(&br->parent->children, &br->children_node);
     589                 :            :     }
     590         [ +  + ]:         35 :     if (br->br_cfg) {
     591                 :         29 :         ovsrec_bridge_delete(br->br_cfg);
     592                 :         29 :         ovs_delete_bridge(vsctl_ctx->ovs, br->br_cfg);
     593                 :            :     }
     594                 :         35 :     shash_find_and_delete(&vsctl_ctx->bridges, br->name);
     595                 :         35 :     hmap_destroy(&br->children);
     596                 :         35 :     free(br->name);
     597                 :         35 :     free(br);
     598                 :         35 : }
     599                 :            : 
     600                 :            : static bool
     601                 :      56334 : port_is_fake_bridge(const struct ovsrec_port *port_cfg)
     602                 :            : {
     603                 :      56334 :     return (port_cfg->fake_bridge
     604         [ +  - ]:        362 :             && port_cfg->tag
     605 [ +  + ][ +  - ]:      56696 :             && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095);
                 [ +  - ]
     606                 :            : }
     607                 :            : 
     608                 :            : static struct vsctl_bridge *
     609                 :        559 : find_vlan_bridge(struct vsctl_bridge *parent, int vlan)
     610                 :            : {
     611                 :            :     struct vsctl_bridge *child;
     612                 :            : 
     613 [ +  + ][ -  + ]:        559 :     HMAP_FOR_EACH_IN_BUCKET (child, children_node, hash_int(vlan, 0),
     614                 :            :                              &parent->children) {
     615         [ +  - ]:        341 :         if (child->vlan == vlan) {
     616                 :        341 :             return child;
     617                 :            :         }
     618                 :            :     }
     619                 :            : 
     620                 :        218 :     return NULL;
     621                 :            : }
     622                 :            : 
     623                 :            : static struct vsctl_port *
     624                 :      30977 : add_port_to_cache(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *parent,
     625                 :            :                   struct ovsrec_port *port_cfg)
     626                 :            : {
     627                 :            :     struct vsctl_port *port;
     628                 :            : 
     629         [ +  + ]:      30977 :     if (port_cfg->tag
     630 [ +  - ][ +  - ]:        363 :         && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095) {
     631                 :            :         struct vsctl_bridge *vlan_bridge;
     632                 :            : 
     633                 :        363 :         vlan_bridge = find_vlan_bridge(parent, *port_cfg->tag);
     634         [ +  + ]:        363 :         if (vlan_bridge) {
     635                 :        339 :             parent = vlan_bridge;
     636                 :            :         }
     637                 :            :     }
     638                 :            : 
     639                 :      30977 :     port = xmalloc(sizeof *port);
     640                 :      30977 :     ovs_list_push_back(&parent->ports, &port->ports_node);
     641                 :      30977 :     ovs_list_init(&port->ifaces);
     642                 :      30977 :     port->port_cfg = port_cfg;
     643                 :      30977 :     port->bridge = parent;
     644                 :      30977 :     shash_add(&vsctl_ctx->ports, port_cfg->name, port);
     645                 :            : 
     646                 :      30977 :     return port;
     647                 :            : }
     648                 :            : 
     649                 :            : static void
     650                 :       1418 : del_cached_port(struct vsctl_context *vsctl_ctx, struct vsctl_port *port)
     651                 :            : {
     652         [ -  + ]:       1418 :     ovs_assert(ovs_list_is_empty(&port->ifaces));
     653                 :       1418 :     ovs_list_remove(&port->ports_node);
     654                 :       1418 :     shash_find_and_delete(&vsctl_ctx->ports, port->port_cfg->name);
     655                 :       1418 :     ovsrec_port_delete(port->port_cfg);
     656                 :       1418 :     free(port);
     657                 :       1418 : }
     658                 :            : 
     659                 :            : static struct vsctl_iface *
     660                 :      31173 : add_iface_to_cache(struct vsctl_context *vsctl_ctx, struct vsctl_port *parent,
     661                 :            :                    struct ovsrec_interface *iface_cfg)
     662                 :            : {
     663                 :            :     struct vsctl_iface *iface;
     664                 :            : 
     665                 :      31173 :     iface = xmalloc(sizeof *iface);
     666                 :      31173 :     ovs_list_push_back(&parent->ifaces, &iface->ifaces_node);
     667                 :      31173 :     iface->iface_cfg = iface_cfg;
     668                 :      31173 :     iface->port = parent;
     669                 :      31173 :     shash_add(&vsctl_ctx->ifaces, iface_cfg->name, iface);
     670                 :            : 
     671                 :      31173 :     return iface;
     672                 :            : }
     673                 :            : 
     674                 :            : static void
     675                 :       1421 : del_cached_iface(struct vsctl_context *vsctl_ctx, struct vsctl_iface *iface)
     676                 :            : {
     677                 :       1421 :     ovs_list_remove(&iface->ifaces_node);
     678                 :       1421 :     shash_find_and_delete(&vsctl_ctx->ifaces, iface->iface_cfg->name);
     679                 :       1421 :     ovsrec_interface_delete(iface->iface_cfg);
     680                 :       1421 :     free(iface);
     681                 :       1421 : }
     682                 :            : 
     683                 :            : static void
     684                 :      17730 : vsctl_context_invalidate_cache(struct ctl_context *ctx)
     685                 :            : {
     686                 :      17730 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
     687                 :            :     struct shash_node *node;
     688                 :            : 
     689         [ +  + ]:      17730 :     if (!vsctl_ctx->cache_valid) {
     690                 :      14776 :         return;
     691                 :            :     }
     692                 :       2954 :     vsctl_ctx->cache_valid = false;
     693                 :            : 
     694 [ +  + ][ -  + ]:       6127 :     SHASH_FOR_EACH (node, &vsctl_ctx->bridges) {
     695                 :       3173 :         struct vsctl_bridge *bridge = node->data;
     696                 :       3173 :         hmap_destroy(&bridge->children);
     697                 :       3173 :         free(bridge->name);
     698                 :       3173 :         free(bridge);
     699                 :            :     }
     700                 :       2954 :     shash_destroy(&vsctl_ctx->bridges);
     701                 :            : 
     702                 :       2954 :     shash_destroy_free_data(&vsctl_ctx->ports);
     703                 :       2954 :     shash_destroy_free_data(&vsctl_ctx->ifaces);
     704                 :            : }
     705                 :            : 
     706                 :            : static void
     707                 :       4387 : pre_get_info(struct ctl_context *ctx)
     708                 :            : {
     709                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_bridges);
     710                 :            : 
     711                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_name);
     712                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
     713                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
     714                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ports);
     715                 :            : 
     716                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_name);
     717                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_fake_bridge);
     718                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_tag);
     719                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_interfaces);
     720                 :            : 
     721                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_name);
     722                 :            : 
     723                 :       4387 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_ofport);
     724                 :       4387 : }
     725                 :            : 
     726                 :            : static void
     727                 :       4387 : vsctl_context_populate_cache(struct ctl_context *ctx)
     728                 :            : {
     729                 :       4387 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
     730                 :       4387 :     const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
     731                 :            :     struct sset bridges, ports;
     732                 :            :     size_t i;
     733                 :            : 
     734         [ +  + ]:       4387 :     if (vsctl_ctx->cache_valid) {
     735                 :            :         /* Cache is already populated. */
     736                 :       1346 :         return;
     737                 :            :     }
     738                 :       3041 :     vsctl_ctx->cache_valid = true;
     739                 :       3041 :     shash_init(&vsctl_ctx->bridges);
     740                 :       3041 :     shash_init(&vsctl_ctx->ports);
     741                 :       3041 :     shash_init(&vsctl_ctx->ifaces);
     742                 :            : 
     743                 :       3041 :     sset_init(&bridges);
     744                 :       3041 :     sset_init(&ports);
     745         [ +  + ]:       6198 :     for (i = 0; i < ovs->n_bridges; i++) {
     746                 :       3157 :         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
     747                 :            :         struct vsctl_bridge *br;
     748                 :            :         size_t j;
     749                 :            : 
     750         [ -  + ]:       3157 :         if (!sset_add(&bridges, br_cfg->name)) {
     751         [ #  # ]:          0 :             VLOG_WARN("%s: database contains duplicate bridge name",
     752                 :            :                       br_cfg->name);
     753                 :          0 :             continue;
     754                 :            :         }
     755                 :       3157 :         br = add_bridge_to_cache(vsctl_ctx, br_cfg, br_cfg->name, NULL, 0);
     756                 :            : 
     757         [ +  + ]:      31324 :         for (j = 0; j < br_cfg->n_ports; j++) {
     758                 :      28167 :             struct ovsrec_port *port_cfg = br_cfg->ports[j];
     759                 :            : 
     760         [ -  + ]:      28167 :             if (!sset_add(&ports, port_cfg->name)) {
     761                 :            :                 /* Duplicate port name.  (We will warn about that later.) */
     762                 :          0 :                 continue;
     763                 :            :             }
     764                 :            : 
     765         [ +  + ]:      28167 :             if (port_is_fake_bridge(port_cfg)
     766         [ +  - ]:        181 :                 && sset_add(&bridges, port_cfg->name)) {
     767                 :        181 :                 add_bridge_to_cache(vsctl_ctx, NULL, port_cfg->name, br,
     768                 :        181 :                                     *port_cfg->tag);
     769                 :            :             }
     770                 :            :         }
     771                 :            :     }
     772                 :       3041 :     sset_destroy(&bridges);
     773                 :       3041 :     sset_destroy(&ports);
     774                 :            : 
     775                 :       3041 :     sset_init(&bridges);
     776         [ +  + ]:       6198 :     for (i = 0; i < ovs->n_bridges; i++) {
     777                 :       3157 :         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
     778                 :            :         struct vsctl_bridge *br;
     779                 :            :         size_t j;
     780                 :            : 
     781         [ -  + ]:       3157 :         if (!sset_add(&bridges, br_cfg->name)) {
     782                 :          0 :             continue;
     783                 :            :         }
     784                 :       3157 :         br = shash_find_data(&vsctl_ctx->bridges, br_cfg->name);
     785         [ +  + ]:      31324 :         for (j = 0; j < br_cfg->n_ports; j++) {
     786                 :      28167 :             struct ovsrec_port *port_cfg = br_cfg->ports[j];
     787                 :            :             struct vsctl_port *port;
     788                 :            :             size_t k;
     789                 :            : 
     790                 :      28167 :             port = shash_find_data(&vsctl_ctx->ports, port_cfg->name);
     791         [ -  + ]:      28167 :             if (port) {
     792         [ #  # ]:          0 :                 if (port_cfg == port->port_cfg) {
     793         [ #  # ]:          0 :                     VLOG_WARN("%s: port is in multiple bridges (%s and %s)",
     794                 :            :                               port_cfg->name, br->name, port->bridge->name);
     795                 :            :                 } else {
     796                 :            :                     /* Log as an error because this violates the database's
     797                 :            :                      * uniqueness constraints, so the database server shouldn't
     798                 :            :                      * have allowed it. */
     799         [ #  # ]:          0 :                     VLOG_ERR("%s: database contains duplicate port name",
     800                 :            :                              port_cfg->name);
     801                 :            :                 }
     802                 :          0 :                 continue;
     803                 :            :             }
     804                 :            : 
     805         [ +  + ]:      28167 :             if (port_is_fake_bridge(port_cfg)
     806         [ -  + ]:        181 :                 && !sset_add(&bridges, port_cfg->name)) {
     807                 :          0 :                 continue;
     808                 :            :             }
     809                 :            : 
     810                 :      28167 :             port = add_port_to_cache(vsctl_ctx, br, port_cfg);
     811         [ +  + ]:      56498 :             for (k = 0; k < port_cfg->n_interfaces; k++) {
     812                 :      28331 :                 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
     813                 :            :                 struct vsctl_iface *iface;
     814                 :            : 
     815                 :      28331 :                 iface = shash_find_data(&vsctl_ctx->ifaces, iface_cfg->name);
     816         [ -  + ]:      28331 :                 if (iface) {
     817         [ #  # ]:          0 :                     if (iface_cfg == iface->iface_cfg) {
     818         [ #  # ]:          0 :                         VLOG_WARN("%s: interface is in multiple ports "
     819                 :            :                                   "(%s and %s)",
     820                 :            :                                   iface_cfg->name,
     821                 :            :                                   iface->port->port_cfg->name,
     822                 :            :                                   port->port_cfg->name);
     823                 :            :                     } else {
     824                 :            :                         /* Log as an error because this violates the database's
     825                 :            :                          * uniqueness constraints, so the database server
     826                 :            :                          * shouldn't have allowed it. */
     827         [ #  # ]:          0 :                         VLOG_ERR("%s: database contains duplicate interface "
     828                 :            :                                  "name", iface_cfg->name);
     829                 :            :                     }
     830                 :          0 :                     continue;
     831                 :            :                 }
     832                 :            : 
     833                 :      28331 :                 add_iface_to_cache(vsctl_ctx, port, iface_cfg);
     834                 :            :             }
     835                 :            :         }
     836                 :            :     }
     837                 :       3041 :     sset_destroy(&bridges);
     838                 :            : }
     839                 :            : 
     840                 :            : static void
     841                 :       6506 : check_conflicts(struct vsctl_context *vsctl_ctx, const char *name,
     842                 :            :                 char *msg)
     843                 :            : {
     844                 :            :     struct vsctl_iface *iface;
     845                 :            :     struct vsctl_port *port;
     846                 :            : 
     847                 :       6506 :     verify_ports(vsctl_ctx);
     848                 :            : 
     849         [ +  + ]:       6506 :     if (shash_find(&vsctl_ctx->bridges, name)) {
     850                 :          1 :         ctl_fatal("%s because a bridge named %s already exists",
     851                 :            :                     msg, name);
     852                 :            :     }
     853                 :            : 
     854                 :       6505 :     port = shash_find_data(&vsctl_ctx->ports, name);
     855         [ +  + ]:       6505 :     if (port) {
     856                 :          1 :         ctl_fatal("%s because a port named %s already exists on "
     857                 :          1 :                     "bridge %s", msg, name, port->bridge->name);
     858                 :            :     }
     859                 :            : 
     860                 :       6504 :     iface = shash_find_data(&vsctl_ctx->ifaces, name);
     861         [ -  + ]:       6504 :     if (iface) {
     862                 :          0 :         ctl_fatal("%s because an interface named %s already exists "
     863                 :          0 :                     "on bridge %s", msg, name, iface->port->bridge->name);
     864                 :            :     }
     865                 :            : 
     866                 :       6504 :     free(msg);
     867                 :       6504 : }
     868                 :            : 
     869                 :            : static struct vsctl_bridge *
     870                 :       3396 : find_bridge(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
     871                 :            : {
     872                 :            :     struct vsctl_bridge *br;
     873                 :            : 
     874         [ -  + ]:       3396 :     ovs_assert(vsctl_ctx->cache_valid);
     875                 :            : 
     876                 :       3396 :     br = shash_find_data(&vsctl_ctx->bridges, name);
     877 [ +  + ][ -  + ]:       3396 :     if (must_exist && !br) {
     878                 :          0 :         ctl_fatal("no bridge named %s", name);
     879                 :            :     }
     880                 :       3396 :     ovsrec_open_vswitch_verify_bridges(vsctl_ctx->ovs);
     881                 :       3396 :     return br;
     882                 :            : }
     883                 :            : 
     884                 :            : static struct vsctl_bridge *
     885                 :         10 : find_real_bridge(struct vsctl_context *vsctl_ctx,
     886                 :            :                  const char *name, bool must_exist)
     887                 :            : {
     888                 :         10 :     struct vsctl_bridge *br = find_bridge(vsctl_ctx, name, must_exist);
     889 [ +  - ][ -  + ]:         10 :     if (br && br->parent) {
     890                 :          0 :         ctl_fatal("%s is a fake bridge", name);
     891                 :            :     }
     892                 :         10 :     return br;
     893                 :            : }
     894                 :            : 
     895                 :            : static struct vsctl_port *
     896                 :        131 : find_port(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
     897                 :            : {
     898                 :            :     struct vsctl_port *port;
     899                 :            : 
     900         [ -  + ]:        131 :     ovs_assert(vsctl_ctx->cache_valid);
     901                 :            : 
     902                 :        131 :     port = shash_find_data(&vsctl_ctx->ports, name);
     903 [ +  + ][ +  + ]:        131 :     if (port && !strcmp(name, port->bridge->name)) {
     904                 :         26 :         port = NULL;
     905                 :            :     }
     906 [ +  + ][ +  + ]:        131 :     if (must_exist && !port) {
     907                 :         26 :         ctl_fatal("no port named %s", name);
     908                 :            :     }
     909                 :        105 :     verify_ports(vsctl_ctx);
     910                 :        105 :     return port;
     911                 :            : }
     912                 :            : 
     913                 :            : static struct vsctl_iface *
     914                 :         64 : find_iface(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
     915                 :            : {
     916                 :            :     struct vsctl_iface *iface;
     917                 :            : 
     918         [ -  + ]:         64 :     ovs_assert(vsctl_ctx->cache_valid);
     919                 :            : 
     920                 :         64 :     iface = shash_find_data(&vsctl_ctx->ifaces, name);
     921 [ +  - ][ +  + ]:         64 :     if (iface && !strcmp(name, iface->port->bridge->name)) {
     922                 :         25 :         iface = NULL;
     923                 :            :     }
     924 [ +  - ][ +  + ]:         64 :     if (must_exist && !iface) {
     925                 :         25 :         ctl_fatal("no interface named %s", name);
     926                 :            :     }
     927                 :         39 :     verify_ports(vsctl_ctx);
     928                 :         39 :     return iface;
     929                 :            : }
     930                 :            : 
     931                 :            : static void
     932                 :       2823 : bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
     933                 :            : {
     934                 :            :     struct ovsrec_port **ports;
     935                 :            :     size_t i;
     936                 :            : 
     937                 :       2823 :     ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
     938         [ +  + ]:      91946 :     for (i = 0; i < br->n_ports; i++) {
     939                 :      89123 :         ports[i] = br->ports[i];
     940                 :            :     }
     941                 :       2823 :     ports[br->n_ports] = port;
     942                 :       2823 :     ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
     943                 :       2823 :     free(ports);
     944                 :       2823 : }
     945                 :            : 
     946                 :            : static void
     947                 :       1418 : bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
     948                 :            : {
     949                 :            :     struct ovsrec_port **ports;
     950                 :            :     size_t i, n;
     951                 :            : 
     952                 :       1418 :     ports = xmalloc(sizeof *br->ports * br->n_ports);
     953         [ +  + ]:      68629 :     for (i = n = 0; i < br->n_ports; i++) {
     954         [ +  + ]:      67211 :         if (br->ports[i] != port) {
     955                 :      65793 :             ports[n++] = br->ports[i];
     956                 :            :         }
     957                 :            :     }
     958                 :       1418 :     ovsrec_bridge_set_ports(br, ports, n);
     959                 :       1418 :     free(ports);
     960                 :       1418 : }
     961                 :            : 
     962                 :            : static void
     963                 :        837 : ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
     964                 :            :                   struct ovsrec_bridge *bridge)
     965                 :            : {
     966                 :            :     struct ovsrec_bridge **bridges;
     967                 :            :     size_t i;
     968                 :            : 
     969                 :        837 :     bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
     970         [ +  + ]:       1054 :     for (i = 0; i < ovs->n_bridges; i++) {
     971                 :        217 :         bridges[i] = ovs->bridges[i];
     972                 :            :     }
     973                 :        837 :     bridges[ovs->n_bridges] = bridge;
     974                 :        837 :     ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
     975                 :        837 :     free(bridges);
     976                 :        837 : }
     977                 :            : 
     978                 :            : static void
     979                 :        627 : cmd_init(struct ctl_context *ctx OVS_UNUSED)
     980                 :            : {
     981                 :        627 : }
     982                 :            : 
     983                 :            : static struct cmd_show_table cmd_show_tables[] = {
     984                 :            :     {&ovsrec_table_open_vswitch,
     985                 :            :      NULL,
     986                 :            :      {&ovsrec_open_vswitch_col_manager_options,
     987                 :            :       &ovsrec_open_vswitch_col_bridges,
     988                 :            :       &ovsrec_open_vswitch_col_ovs_version},
     989                 :            :      {NULL, NULL, NULL}
     990                 :            :     },
     991                 :            : 
     992                 :            :     {&ovsrec_table_bridge,
     993                 :            :      &ovsrec_bridge_col_name,
     994                 :            :      {&ovsrec_bridge_col_controller,
     995                 :            :       &ovsrec_bridge_col_fail_mode,
     996                 :            :       &ovsrec_bridge_col_ports},
     997                 :            :      {NULL, NULL, NULL}
     998                 :            :     },
     999                 :            : 
    1000                 :            :     {&ovsrec_table_port,
    1001                 :            :      &ovsrec_port_col_name,
    1002                 :            :      {&ovsrec_port_col_tag,
    1003                 :            :       &ovsrec_port_col_trunks,
    1004                 :            :       &ovsrec_port_col_interfaces},
    1005                 :            :      {NULL, NULL, NULL}
    1006                 :            :     },
    1007                 :            : 
    1008                 :            :     {&ovsrec_table_interface,
    1009                 :            :      &ovsrec_interface_col_name,
    1010                 :            :      {&ovsrec_interface_col_type,
    1011                 :            :       &ovsrec_interface_col_options,
    1012                 :            :       &ovsrec_interface_col_error},
    1013                 :            :      {NULL, NULL, NULL}
    1014                 :            :     },
    1015                 :            : 
    1016                 :            :     {&ovsrec_table_controller,
    1017                 :            :      &ovsrec_controller_col_target,
    1018                 :            :      {&ovsrec_controller_col_is_connected,
    1019                 :            :       NULL,
    1020                 :            :       NULL},
    1021                 :            :      {NULL, NULL, NULL}
    1022                 :            :     },
    1023                 :            : 
    1024                 :            :     {&ovsrec_table_manager,
    1025                 :            :      &ovsrec_manager_col_target,
    1026                 :            :      {&ovsrec_manager_col_is_connected,
    1027                 :            :       NULL,
    1028                 :            :       NULL},
    1029                 :            :      {NULL, NULL, NULL}
    1030                 :            :     },
    1031                 :            : 
    1032                 :            :     {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}}
    1033                 :            : };
    1034                 :            : 
    1035                 :            : static void
    1036                 :          0 : pre_cmd_emer_reset(struct ctl_context *ctx)
    1037                 :            : {
    1038                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
    1039                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
    1040                 :            : 
    1041                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
    1042                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
    1043                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_mirrors);
    1044                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_netflow);
    1045                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_sflow);
    1046                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ipfix);
    1047                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_flood_vlans);
    1048                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_other_config);
    1049                 :            : 
    1050                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_other_config);
    1051                 :            : 
    1052                 :          0 :     ovsdb_idl_add_column(ctx->idl,
    1053                 :            :                           &ovsrec_interface_col_ingress_policing_rate);
    1054                 :          0 :     ovsdb_idl_add_column(ctx->idl,
    1055                 :            :                           &ovsrec_interface_col_ingress_policing_burst);
    1056                 :          0 : }
    1057                 :            : 
    1058                 :            : static void
    1059                 :          0 : cmd_emer_reset(struct ctl_context *ctx)
    1060                 :            : {
    1061                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1062                 :          0 :     const struct ovsdb_idl *idl = ctx->idl;
    1063                 :            :     const struct ovsrec_bridge *br;
    1064                 :            :     const struct ovsrec_port *port;
    1065                 :            :     const struct ovsrec_interface *iface;
    1066                 :            :     const struct ovsrec_mirror *mirror, *next_mirror;
    1067                 :            :     const struct ovsrec_controller *ctrl, *next_ctrl;
    1068                 :            :     const struct ovsrec_manager *mgr, *next_mgr;
    1069                 :            :     const struct ovsrec_netflow *nf, *next_nf;
    1070                 :            :     const struct ovsrec_ssl *ssl, *next_ssl;
    1071                 :            :     const struct ovsrec_sflow *sflow, *next_sflow;
    1072                 :            :     const struct ovsrec_ipfix *ipfix, *next_ipfix;
    1073                 :            :     const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
    1074                 :            : 
    1075                 :            :     /* Reset the Open_vSwitch table. */
    1076                 :          0 :     ovsrec_open_vswitch_set_manager_options(vsctl_ctx->ovs, NULL, 0);
    1077                 :          0 :     ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
    1078                 :            : 
    1079         [ #  # ]:          0 :     OVSREC_BRIDGE_FOR_EACH (br, idl) {
    1080                 :            :         const char *hwaddr;
    1081                 :            : 
    1082                 :          0 :         ovsrec_bridge_set_controller(br, NULL, 0);
    1083                 :          0 :         ovsrec_bridge_set_fail_mode(br, NULL);
    1084                 :          0 :         ovsrec_bridge_set_mirrors(br, NULL, 0);
    1085                 :          0 :         ovsrec_bridge_set_netflow(br, NULL);
    1086                 :          0 :         ovsrec_bridge_set_sflow(br, NULL);
    1087                 :          0 :         ovsrec_bridge_set_ipfix(br, NULL);
    1088                 :          0 :         ovsrec_bridge_set_flood_vlans(br, NULL, 0);
    1089                 :            : 
    1090                 :            :         /* We only want to save the "hwaddr" key from other_config. */
    1091                 :          0 :         hwaddr = smap_get(&br->other_config, "hwaddr");
    1092         [ #  # ]:          0 :         if (hwaddr) {
    1093                 :          0 :             const struct smap smap = SMAP_CONST1(&smap, "hwaddr", hwaddr);
    1094                 :          0 :             ovsrec_bridge_set_other_config(br, &smap);
    1095                 :            :         } else {
    1096                 :          0 :             ovsrec_bridge_set_other_config(br, NULL);
    1097                 :            :         }
    1098                 :            :     }
    1099                 :            : 
    1100         [ #  # ]:          0 :     OVSREC_PORT_FOR_EACH (port, idl) {
    1101                 :          0 :         ovsrec_port_set_other_config(port, NULL);
    1102                 :            :     }
    1103                 :            : 
    1104         [ #  # ]:          0 :     OVSREC_INTERFACE_FOR_EACH (iface, idl) {
    1105                 :            :         /* xxx What do we do about gre/patch devices created by mgr? */
    1106                 :            : 
    1107                 :          0 :         ovsrec_interface_set_ingress_policing_rate(iface, 0);
    1108                 :          0 :         ovsrec_interface_set_ingress_policing_burst(iface, 0);
    1109                 :            :     }
    1110                 :            : 
    1111 [ #  # ][ #  # ]:          0 :     OVSREC_MIRROR_FOR_EACH_SAFE (mirror, next_mirror, idl) {
    1112                 :          0 :         ovsrec_mirror_delete(mirror);
    1113                 :            :     }
    1114                 :            : 
    1115 [ #  # ][ #  # ]:          0 :     OVSREC_CONTROLLER_FOR_EACH_SAFE (ctrl, next_ctrl, idl) {
    1116                 :          0 :         ovsrec_controller_delete(ctrl);
    1117                 :            :     }
    1118                 :            : 
    1119 [ #  # ][ #  # ]:          0 :     OVSREC_MANAGER_FOR_EACH_SAFE (mgr, next_mgr, idl) {
    1120                 :          0 :         ovsrec_manager_delete(mgr);
    1121                 :            :     }
    1122                 :            : 
    1123 [ #  # ][ #  # ]:          0 :     OVSREC_NETFLOW_FOR_EACH_SAFE (nf, next_nf, idl) {
    1124                 :          0 :         ovsrec_netflow_delete(nf);
    1125                 :            :     }
    1126                 :            : 
    1127 [ #  # ][ #  # ]:          0 :     OVSREC_SSL_FOR_EACH_SAFE (ssl, next_ssl, idl) {
    1128                 :          0 :         ovsrec_ssl_delete(ssl);
    1129                 :            :     }
    1130                 :            : 
    1131 [ #  # ][ #  # ]:          0 :     OVSREC_SFLOW_FOR_EACH_SAFE (sflow, next_sflow, idl) {
    1132                 :          0 :         ovsrec_sflow_delete(sflow);
    1133                 :            :     }
    1134                 :            : 
    1135 [ #  # ][ #  # ]:          0 :     OVSREC_IPFIX_FOR_EACH_SAFE (ipfix, next_ipfix, idl) {
    1136                 :          0 :         ovsrec_ipfix_delete(ipfix);
    1137                 :            :     }
    1138                 :            : 
    1139 [ #  # ][ #  # ]:          0 :     OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset, idl) {
    1140                 :          0 :         ovsrec_flow_sample_collector_set_delete(fscset);
    1141                 :            :     }
    1142                 :            : 
    1143                 :          0 :     vsctl_context_invalidate_cache(ctx);
    1144                 :          0 : }
    1145                 :            : 
    1146                 :            : static void
    1147                 :        880 : cmd_add_br(struct ctl_context *ctx)
    1148                 :            : {
    1149                 :        880 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1150                 :        880 :     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
    1151                 :            :     const char *br_name, *parent_name;
    1152                 :            :     struct ovsrec_interface *iface;
    1153                 :            :     int vlan;
    1154                 :            : 
    1155                 :        880 :     br_name = ctx->argv[1];
    1156         [ +  + ]:        880 :     if (ctx->argc == 2) {
    1157                 :        850 :         parent_name = NULL;
    1158                 :        850 :         vlan = 0;
    1159         [ +  - ]:         30 :     } else if (ctx->argc == 4) {
    1160                 :         30 :         parent_name = ctx->argv[2];
    1161                 :         30 :         vlan = atoi(ctx->argv[3]);
    1162 [ +  - ][ -  + ]:         30 :         if (vlan < 0 || vlan > 4095) {
    1163                 :          0 :             ctl_fatal("%s: vlan must be between 0 and 4095", ctx->argv[0]);
    1164                 :            :         }
    1165                 :            :     } else {
    1166                 :          0 :         ctl_fatal("'%s' command takes exactly 1 or 3 arguments",
    1167                 :          0 :                     ctx->argv[0]);
    1168                 :            :     }
    1169                 :            : 
    1170                 :        880 :     vsctl_context_populate_cache(ctx);
    1171         [ +  + ]:        880 :     if (may_exist) {
    1172                 :            :         struct vsctl_bridge *br;
    1173                 :            : 
    1174                 :         38 :         br = find_bridge(vsctl_ctx, br_name, false);
    1175         [ +  + ]:         38 :         if (br) {
    1176         [ +  + ]:         27 :             if (!parent_name) {
    1177         [ +  + ]:         12 :                 if (br->parent) {
    1178                 :          2 :                     ctl_fatal("\"--may-exist add-br %s\" but %s is "
    1179                 :            :                                 "a VLAN bridge for VLAN %d",
    1180                 :            :                                 br_name, br_name, br->vlan);
    1181                 :            :                 }
    1182                 :            :             } else {
    1183         [ +  + ]:         15 :                 if (!br->parent) {
    1184                 :          1 :                     ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
    1185                 :            :                                 "is not a VLAN bridge",
    1186                 :            :                                 br_name, parent_name, vlan, br_name);
    1187         [ +  + ]:         14 :                 } else if (strcmp(br->parent->name, parent_name)) {
    1188                 :          2 :                     ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
    1189                 :            :                                 "has the wrong parent %s",
    1190                 :            :                                 br_name, parent_name, vlan,
    1191                 :          2 :                                 br_name, br->parent->name);
    1192         [ +  + ]:         12 :                 } else if (br->vlan != vlan) {
    1193                 :          2 :                     ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
    1194                 :            :                                 "is a VLAN bridge for the wrong VLAN %d",
    1195                 :            :                                 br_name, parent_name, vlan, br_name, br->vlan);
    1196                 :            :                 }
    1197                 :            :             }
    1198                 :         20 :             return;
    1199                 :            :         }
    1200                 :            :     }
    1201                 :        853 :     check_conflicts(vsctl_ctx, br_name,
    1202                 :            :                     xasprintf("cannot create a bridge named %s", br_name));
    1203                 :            : 
    1204         [ +  + ]:        852 :     if (!parent_name) {
    1205                 :            :         struct ovsrec_port *port;
    1206                 :            :         struct ovsrec_bridge *br;
    1207                 :            : 
    1208                 :        837 :         iface = ovsrec_interface_insert(ctx->txn);
    1209                 :        837 :         ovsrec_interface_set_name(iface, br_name);
    1210                 :        837 :         ovsrec_interface_set_type(iface, "internal");
    1211                 :            : 
    1212                 :        837 :         port = ovsrec_port_insert(ctx->txn);
    1213                 :        837 :         ovsrec_port_set_name(port, br_name);
    1214                 :        837 :         ovsrec_port_set_interfaces(port, &iface, 1);
    1215                 :            : 
    1216                 :        837 :         br = ovsrec_bridge_insert(ctx->txn);
    1217                 :        837 :         ovsrec_bridge_set_name(br, br_name);
    1218                 :        837 :         ovsrec_bridge_set_ports(br, &port, 1);
    1219                 :            : 
    1220                 :        837 :         ovs_insert_bridge(vsctl_ctx->ovs, br);
    1221                 :            :     } else {
    1222                 :            :         struct vsctl_bridge *conflict;
    1223                 :            :         struct vsctl_bridge *parent;
    1224                 :            :         struct ovsrec_port *port;
    1225                 :            :         struct ovsrec_bridge *br;
    1226                 :         15 :         int64_t tag = vlan;
    1227                 :            : 
    1228                 :         15 :         parent = find_bridge(vsctl_ctx, parent_name, false);
    1229 [ +  - ][ -  + ]:         15 :         if (parent && parent->parent) {
    1230                 :          0 :             ctl_fatal("cannot create bridge with fake bridge as parent");
    1231                 :            :         }
    1232         [ -  + ]:         15 :         if (!parent) {
    1233                 :          0 :             ctl_fatal("parent bridge %s does not exist", parent_name);
    1234                 :            :         }
    1235                 :         15 :         conflict = find_vlan_bridge(parent, vlan);
    1236         [ +  + ]:         15 :         if (conflict) {
    1237                 :          2 :             ctl_fatal("bridge %s already has a child VLAN bridge %s "
    1238                 :            :                         "on VLAN %d", parent_name, conflict->name, vlan);
    1239                 :            :         }
    1240                 :         13 :         br = parent->br_cfg;
    1241                 :            : 
    1242                 :         13 :         iface = ovsrec_interface_insert(ctx->txn);
    1243                 :         13 :         ovsrec_interface_set_name(iface, br_name);
    1244                 :         13 :         ovsrec_interface_set_type(iface, "internal");
    1245                 :            : 
    1246                 :         13 :         port = ovsrec_port_insert(ctx->txn);
    1247                 :         13 :         ovsrec_port_set_name(port, br_name);
    1248                 :         13 :         ovsrec_port_set_interfaces(port, &iface, 1);
    1249                 :         13 :         ovsrec_port_set_fake_bridge(port, true);
    1250                 :         13 :         ovsrec_port_set_tag(port, &tag, 1);
    1251                 :            : 
    1252                 :         13 :         bridge_insert_port(br, port);
    1253                 :            :     }
    1254                 :            : 
    1255                 :        850 :     post_db_reload_expect_iface(iface);
    1256                 :        850 :     vsctl_context_invalidate_cache(ctx);
    1257                 :            : }
    1258                 :            : 
    1259                 :            : static void
    1260                 :       1418 : del_port(struct vsctl_context *vsctl_ctx, struct vsctl_port *port)
    1261                 :            : {
    1262                 :            :     struct vsctl_iface *iface, *next_iface;
    1263                 :            : 
    1264         [ +  + ]:       1418 :     bridge_delete_port((port->bridge->parent
    1265                 :         12 :                         ? port->bridge->parent->br_cfg
    1266                 :       1406 :                         : port->bridge->br_cfg), port->port_cfg);
    1267                 :            : 
    1268 [ +  + ][ +  + ]:       2839 :     LIST_FOR_EACH_SAFE (iface, next_iface, ifaces_node, &port->ifaces) {
    1269                 :       1421 :         del_cached_iface(vsctl_ctx, iface);
    1270                 :            :     }
    1271                 :       1418 :     del_cached_port(vsctl_ctx, port);
    1272                 :       1418 : }
    1273                 :            : 
    1274                 :            : static void
    1275                 :         35 : del_bridge(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *br)
    1276                 :            : {
    1277                 :            :     struct vsctl_bridge *child, *next_child;
    1278                 :            :     struct vsctl_port *port, *next_port;
    1279                 :            :     const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
    1280                 :            : 
    1281 [ +  + ][ -  + ]:         38 :     HMAP_FOR_EACH_SAFE (child, next_child, children_node, &br->children) {
                 [ +  + ]
    1282                 :          3 :         del_bridge(vsctl_ctx, child);
    1283                 :            :     }
    1284                 :            : 
    1285 [ +  + ][ +  + ]:       1390 :     LIST_FOR_EACH_SAFE (port, next_port, ports_node, &br->ports) {
    1286                 :       1355 :         del_port(vsctl_ctx, port);
    1287                 :            :     }
    1288                 :            : 
    1289 [ -  + ][ -  + ]:         35 :     OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset,
    1290                 :            :                                                     vsctl_ctx->base.idl) {
    1291         [ #  # ]:          0 :         if (fscset->bridge == br->br_cfg) {
    1292                 :          0 :             ovsrec_flow_sample_collector_set_delete(fscset);
    1293                 :            :         }
    1294                 :            :     }
    1295                 :            : 
    1296                 :         35 :     del_cached_bridge(vsctl_ctx, br);
    1297                 :         35 : }
    1298                 :            : 
    1299                 :            : static void
    1300                 :         33 : cmd_del_br(struct ctl_context *ctx)
    1301                 :            : {
    1302                 :         33 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1303                 :         33 :     bool must_exist = !shash_find(&ctx->options, "--if-exists");
    1304                 :            :     struct vsctl_bridge *bridge;
    1305                 :            : 
    1306                 :         33 :     vsctl_context_populate_cache(ctx);
    1307                 :         33 :     bridge = find_bridge(vsctl_ctx, ctx->argv[1], must_exist);
    1308         [ +  + ]:         33 :     if (bridge) {
    1309                 :         32 :         del_bridge(vsctl_ctx, bridge);
    1310                 :            :     }
    1311                 :         33 : }
    1312                 :            : 
    1313                 :            : static void
    1314                 :        224 : output_sorted(struct svec *svec, struct ds *output)
    1315                 :            : {
    1316                 :            :     const char *name;
    1317                 :            :     size_t i;
    1318                 :            : 
    1319                 :        224 :     svec_sort(svec);
    1320 [ +  + ][ +  + ]:        519 :     SVEC_FOR_EACH (i, name, svec) {
    1321                 :        295 :         ds_put_format(output, "%s\n", name);
    1322                 :            :     }
    1323                 :        224 : }
    1324                 :            : 
    1325                 :            : static void
    1326                 :         87 : cmd_list_br(struct ctl_context *ctx)
    1327                 :            : {
    1328                 :         87 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1329                 :            :     struct shash_node *node;
    1330                 :            :     struct svec bridges;
    1331                 :         87 :     bool real = shash_find(&ctx->options, "--real");
    1332                 :         87 :     bool fake = shash_find(&ctx->options, "--fake");
    1333                 :            : 
    1334                 :            :     /* If neither fake nor real were requested, return both. */
    1335 [ +  + ][ +  + ]:         87 :     if (!real && !fake) {
    1336                 :         83 :         real = fake = true;
    1337                 :            :     }
    1338                 :            : 
    1339                 :         87 :     vsctl_context_populate_cache(ctx);
    1340                 :            : 
    1341                 :         87 :     svec_init(&bridges);
    1342 [ +  + ][ -  + ]:        243 :     SHASH_FOR_EACH (node, &vsctl_ctx->bridges) {
    1343                 :        156 :         struct vsctl_bridge *br = node->data;
    1344                 :            : 
    1345 [ +  + ][ +  + ]:        156 :         if (br->parent ? fake : real) {
    1346                 :        152 :             svec_add(&bridges, br->name);
    1347                 :            :         }
    1348                 :            :     }
    1349                 :         87 :     output_sorted(&bridges, &ctx->output);
    1350                 :         87 :     svec_destroy(&bridges);
    1351                 :         87 : }
    1352                 :            : 
    1353                 :            : static void
    1354                 :         48 : cmd_br_exists(struct ctl_context *ctx)
    1355                 :            : {
    1356                 :         48 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1357                 :            : 
    1358                 :         48 :     vsctl_context_populate_cache(ctx);
    1359         [ +  + ]:         48 :     if (!find_bridge(vsctl_ctx, ctx->argv[1], false)) {
    1360                 :         22 :         vsctl_exit(2);
    1361                 :            :     }
    1362                 :         26 : }
    1363                 :            : 
    1364                 :            : static void
    1365                 :         27 : set_external_id(struct smap *old, struct smap *new,
    1366                 :            :                 char *key, char *value)
    1367                 :            : {
    1368                 :         27 :     smap_clone(new, old);
    1369                 :            : 
    1370         [ +  + ]:         27 :     if (value) {
    1371                 :         26 :         smap_replace(new, key, value);
    1372                 :            :     } else {
    1373                 :          1 :         smap_remove(new, key);
    1374                 :            :     }
    1375                 :         27 : }
    1376                 :            : 
    1377                 :            : static void
    1378                 :         55 : pre_cmd_br_set_external_id(struct ctl_context *ctx)
    1379                 :            : {
    1380                 :         55 :     pre_get_info(ctx);
    1381                 :         55 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_external_ids);
    1382                 :         55 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_external_ids);
    1383                 :         55 : }
    1384                 :            : 
    1385                 :            : static void
    1386                 :         27 : cmd_br_set_external_id(struct ctl_context *ctx)
    1387                 :            : {
    1388                 :         27 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1389                 :            :     struct vsctl_bridge *bridge;
    1390                 :            :     struct smap new;
    1391                 :            : 
    1392                 :         27 :     vsctl_context_populate_cache(ctx);
    1393                 :         27 :     bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1394         [ +  + ]:         27 :     if (bridge->br_cfg) {
    1395                 :            : 
    1396         [ +  + ]:         25 :         set_external_id(&bridge->br_cfg->external_ids, &new, ctx->argv[2],
    1397                 :         49 :                         ctx->argc >= 4 ? ctx->argv[3] : NULL);
    1398                 :         25 :         ovsrec_bridge_verify_external_ids(bridge->br_cfg);
    1399                 :         25 :         ovsrec_bridge_set_external_ids(bridge->br_cfg, &new);
    1400                 :            :     } else {
    1401                 :          2 :         char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
    1402                 :          2 :         struct vsctl_port *port = shash_find_data(&vsctl_ctx->ports,
    1403                 :          2 :                                                   ctx->argv[1]);
    1404         [ +  - ]:          2 :         set_external_id(&port->port_cfg->external_ids, &new,
    1405                 :          4 :                         key, ctx->argc >= 4 ? ctx->argv[3] : NULL);
    1406                 :          2 :         ovsrec_port_verify_external_ids(port->port_cfg);
    1407                 :          2 :         ovsrec_port_set_external_ids(port->port_cfg, &new);
    1408                 :          2 :         free(key);
    1409                 :            :     }
    1410                 :         27 :     smap_destroy(&new);
    1411                 :         27 : }
    1412                 :            : 
    1413                 :            : static void
    1414                 :         28 : get_external_id(struct smap *smap, const char *prefix, const char *key,
    1415                 :            :                 struct ds *output)
    1416                 :            : {
    1417         [ +  + ]:         28 :     if (key) {
    1418                 :         14 :         char *prefix_key = xasprintf("%s%s", prefix, key);
    1419                 :         14 :         const char *value = smap_get(smap, prefix_key);
    1420                 :            : 
    1421         [ +  + ]:         14 :         if (value) {
    1422                 :          5 :             ds_put_format(output, "%s\n", value);
    1423                 :            :         }
    1424                 :         14 :         free(prefix_key);
    1425                 :            :     } else {
    1426                 :         14 :         const struct smap_node **sorted = smap_sort(smap);
    1427                 :         14 :         size_t prefix_len = strlen(prefix);
    1428                 :            :         size_t i;
    1429                 :            : 
    1430         [ +  + ]:         24 :         for (i = 0; i < smap_count(smap); i++) {
    1431                 :         10 :             const struct smap_node *node = sorted[i];
    1432         [ +  - ]:         10 :             if (!strncmp(node->key, prefix, prefix_len)) {
    1433                 :         10 :                 ds_put_format(output, "%s=%s\n", node->key + prefix_len,
    1434                 :            :                               node->value);
    1435                 :            :             }
    1436                 :            :         }
    1437                 :         14 :         free(sorted);
    1438                 :            :     }
    1439                 :         28 : }
    1440                 :            : 
    1441                 :            : static void
    1442                 :         28 : pre_cmd_br_get_external_id(struct ctl_context *ctx)
    1443                 :            : {
    1444                 :         28 :     pre_cmd_br_set_external_id(ctx);
    1445                 :         28 : }
    1446                 :            : 
    1447                 :            : static void
    1448                 :         28 : cmd_br_get_external_id(struct ctl_context *ctx)
    1449                 :            : {
    1450                 :         28 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1451                 :            :     struct vsctl_bridge *bridge;
    1452                 :            : 
    1453                 :         28 :     vsctl_context_populate_cache(ctx);
    1454                 :            : 
    1455                 :         28 :     bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1456         [ +  + ]:         28 :     if (bridge->br_cfg) {
    1457                 :         24 :         ovsrec_bridge_verify_external_ids(bridge->br_cfg);
    1458         [ +  + ]:         24 :         get_external_id(&bridge->br_cfg->external_ids, "",
    1459                 :         36 :                         ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
    1460                 :            :     } else {
    1461                 :          4 :         struct vsctl_port *port = shash_find_data(&vsctl_ctx->ports,
    1462                 :          4 :                                                   ctx->argv[1]);
    1463                 :          4 :         ovsrec_port_verify_external_ids(port->port_cfg);
    1464         [ +  + ]:          4 :         get_external_id(&port->port_cfg->external_ids, "fake-bridge-",
    1465                 :          6 :                         ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
    1466                 :            :     }
    1467                 :         28 : }
    1468                 :            : 
    1469                 :            : static void
    1470                 :         96 : cmd_list_ports(struct ctl_context *ctx)
    1471                 :            : {
    1472                 :         96 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1473                 :            :     struct vsctl_bridge *br;
    1474                 :            :     struct vsctl_port *port;
    1475                 :            :     struct svec ports;
    1476                 :            : 
    1477                 :         96 :     vsctl_context_populate_cache(ctx);
    1478                 :         96 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1479         [ +  + ]:         96 :     ovsrec_bridge_verify_ports(br->br_cfg ? br->br_cfg : br->parent->br_cfg);
    1480                 :            : 
    1481                 :         96 :     svec_init(&ports);
    1482         [ +  + ]:        288 :     LIST_FOR_EACH (port, ports_node, &br->ports) {
    1483         [ +  + ]:        192 :         if (strcmp(port->port_cfg->name, br->name)) {
    1484                 :         96 :             svec_add(&ports, port->port_cfg->name);
    1485                 :            :         }
    1486                 :            :     }
    1487                 :         96 :     output_sorted(&ports, &ctx->output);
    1488                 :         96 :     svec_destroy(&ports);
    1489                 :         96 : }
    1490                 :            : 
    1491                 :            : static void
    1492                 :       2825 : add_port(struct ctl_context *ctx,
    1493                 :            :          const char *br_name, const char *port_name,
    1494                 :            :          bool may_exist, bool fake_iface,
    1495                 :            :          char *iface_names[], int n_ifaces,
    1496                 :            :          char *settings[], int n_settings)
    1497                 :            : {
    1498                 :       2825 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1499                 :            :     struct vsctl_port *vsctl_port;
    1500                 :            :     struct vsctl_bridge *bridge;
    1501                 :            :     struct ovsrec_interface **ifaces;
    1502                 :            :     struct ovsrec_port *port;
    1503                 :            :     size_t i;
    1504                 :            : 
    1505                 :       2825 :     vsctl_context_populate_cache(ctx);
    1506         [ +  + ]:       2825 :     if (may_exist) {
    1507                 :            :         struct vsctl_port *vsctl_port;
    1508                 :            : 
    1509                 :         19 :         vsctl_port = find_port(vsctl_ctx, port_name, false);
    1510         [ +  + ]:         19 :         if (vsctl_port) {
    1511                 :            :             struct svec want_names, have_names;
    1512                 :            : 
    1513                 :         14 :             svec_init(&want_names);
    1514         [ +  + ]:         31 :             for (i = 0; i < n_ifaces; i++) {
    1515                 :         17 :                 svec_add(&want_names, iface_names[i]);
    1516                 :            :             }
    1517                 :         14 :             svec_sort(&want_names);
    1518                 :            : 
    1519                 :         14 :             svec_init(&have_names);
    1520         [ +  + ]:         32 :             for (i = 0; i < vsctl_port->port_cfg->n_interfaces; i++) {
    1521                 :         18 :                 svec_add(&have_names,
    1522                 :         18 :                          vsctl_port->port_cfg->interfaces[i]->name);
    1523                 :            :             }
    1524                 :         14 :             svec_sort(&have_names);
    1525                 :            : 
    1526         [ +  + ]:         14 :             if (strcmp(vsctl_port->bridge->name, br_name)) {
    1527                 :          1 :                 char *command = vsctl_context_to_string(ctx);
    1528                 :          1 :                 ctl_fatal("\"%s\" but %s is actually attached to bridge %s",
    1529                 :          1 :                             command, port_name, vsctl_port->bridge->name);
    1530                 :            :             }
    1531                 :            : 
    1532         [ +  + ]:         13 :             if (!svec_equal(&want_names, &have_names)) {
    1533                 :          1 :                 char *have_names_string = svec_join(&have_names, ", ", "");
    1534                 :          1 :                 char *command = vsctl_context_to_string(ctx);
    1535                 :            : 
    1536                 :          1 :                 ctl_fatal("\"%s\" but %s actually has interface(s) %s",
    1537                 :            :                             command, port_name, have_names_string);
    1538                 :            :             }
    1539                 :            : 
    1540                 :         12 :             svec_destroy(&want_names);
    1541                 :         12 :             svec_destroy(&have_names);
    1542                 :            : 
    1543                 :         12 :             return;
    1544                 :            :         }
    1545                 :            :     }
    1546                 :       2811 :     check_conflicts(vsctl_ctx, port_name,
    1547                 :            :                     xasprintf("cannot create a port named %s", port_name));
    1548         [ +  + ]:       5652 :     for (i = 0; i < n_ifaces; i++) {
    1549                 :       2842 :         check_conflicts(vsctl_ctx, iface_names[i],
    1550                 :            :                         xasprintf("cannot create an interface named %s",
    1551                 :       2842 :                                   iface_names[i]));
    1552                 :            :     }
    1553                 :       2810 :     bridge = find_bridge(vsctl_ctx, br_name, true);
    1554                 :            : 
    1555                 :       2810 :     ifaces = xmalloc(n_ifaces * sizeof *ifaces);
    1556         [ +  + ]:       5652 :     for (i = 0; i < n_ifaces; i++) {
    1557                 :       2842 :         ifaces[i] = ovsrec_interface_insert(ctx->txn);
    1558                 :       2842 :         ovsrec_interface_set_name(ifaces[i], iface_names[i]);
    1559                 :       2842 :         post_db_reload_expect_iface(ifaces[i]);
    1560                 :            :     }
    1561                 :            : 
    1562                 :       2810 :     port = ovsrec_port_insert(ctx->txn);
    1563                 :       2810 :     ovsrec_port_set_name(port, port_name);
    1564                 :       2810 :     ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
    1565                 :       2810 :     ovsrec_port_set_bond_fake_iface(port, fake_iface);
    1566                 :            : 
    1567         [ +  + ]:       2810 :     if (bridge->parent) {
    1568                 :         13 :         int64_t tag = bridge->vlan;
    1569                 :         13 :         ovsrec_port_set_tag(port, &tag, 1);
    1570                 :            :     }
    1571                 :            : 
    1572         [ +  + ]:       2871 :     for (i = 0; i < n_settings; i++) {
    1573                 :         61 :         ctl_set_column("Port", &port->header_, settings[i],
    1574                 :            :                        ctx->symtab);
    1575                 :            :     }
    1576                 :            : 
    1577         [ +  + ]:       2810 :     bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
    1578                 :            :                         : bridge->br_cfg), port);
    1579                 :            : 
    1580                 :       2810 :     vsctl_port = add_port_to_cache(vsctl_ctx, bridge, port);
    1581         [ +  + ]:       5652 :     for (i = 0; i < n_ifaces; i++) {
    1582                 :       2842 :         add_iface_to_cache(vsctl_ctx, vsctl_port, ifaces[i]);
    1583                 :            :     }
    1584                 :       2810 :     free(ifaces);
    1585                 :            : }
    1586                 :            : 
    1587                 :            : static void
    1588                 :       2796 : cmd_add_port(struct ctl_context *ctx)
    1589                 :            : {
    1590                 :       2796 :     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
    1591                 :            : 
    1592                 :       2796 :     add_port(ctx, ctx->argv[1], ctx->argv[2], may_exist, false,
    1593                 :       8388 :              &ctx->argv[2], 1, &ctx->argv[3], ctx->argc - 3);
    1594                 :       2794 : }
    1595                 :            : 
    1596                 :            : static void
    1597                 :         29 : cmd_add_bond(struct ctl_context *ctx)
    1598                 :            : {
    1599                 :         29 :     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
    1600                 :         29 :     bool fake_iface = shash_find(&ctx->options, "--fake-iface");
    1601                 :            :     int n_ifaces;
    1602                 :            :     int i;
    1603                 :            : 
    1604                 :         29 :     n_ifaces = ctx->argc - 3;
    1605         [ +  + ]:         93 :     for (i = 3; i < ctx->argc; i++) {
    1606         [ +  + ]:         82 :         if (strchr(ctx->argv[i], '=')) {
    1607                 :         18 :             n_ifaces = i - 3;
    1608                 :         18 :             break;
    1609                 :            :         }
    1610                 :            :     }
    1611         [ -  + ]:         29 :     if (n_ifaces < 2) {
    1612                 :          0 :         ctl_fatal("add-bond requires at least 2 interfaces, but only "
    1613                 :            :                     "%d were specified", n_ifaces);
    1614                 :            :     }
    1615                 :            : 
    1616                 :         29 :     add_port(ctx, ctx->argv[1], ctx->argv[2], may_exist, fake_iface,
    1617                 :         29 :              &ctx->argv[3], n_ifaces,
    1618                 :         58 :              &ctx->argv[n_ifaces + 3], ctx->argc - 3 - n_ifaces);
    1619                 :         28 : }
    1620                 :            : 
    1621                 :            : static void
    1622                 :         66 : cmd_del_port(struct ctl_context *ctx)
    1623                 :            : {
    1624                 :         66 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1625                 :         66 :     bool must_exist = !shash_find(&ctx->options, "--if-exists");
    1626                 :         66 :     bool with_iface = shash_find(&ctx->options, "--with-iface") != NULL;
    1627                 :         66 :     const char *target = ctx->argv[ctx->argc - 1];
    1628                 :            :     struct vsctl_port *port;
    1629                 :            : 
    1630                 :         66 :     vsctl_context_populate_cache(ctx);
    1631         [ +  + ]:         66 :     if (find_bridge(vsctl_ctx, target, false)) {
    1632         [ +  + ]:          2 :         if (must_exist) {
    1633                 :          1 :             ctl_fatal("cannot delete port %s because it is the local port "
    1634                 :            :                         "for bridge %s (deleting this port requires deleting "
    1635                 :            :                         "the entire bridge)", target, target);
    1636                 :            :         }
    1637                 :          1 :         port = NULL;
    1638         [ +  - ]:         64 :     } else if (!with_iface) {
    1639                 :         64 :         port = find_port(vsctl_ctx, target, must_exist);
    1640                 :            :     } else {
    1641                 :            :         struct vsctl_iface *iface;
    1642                 :            : 
    1643                 :          0 :         port = find_port(vsctl_ctx, target, false);
    1644         [ #  # ]:          0 :         if (!port) {
    1645                 :          0 :             iface = find_iface(vsctl_ctx, target, false);
    1646         [ #  # ]:          0 :             if (iface) {
    1647                 :          0 :                 port = iface->port;
    1648                 :            :             }
    1649                 :            :         }
    1650 [ #  # ][ #  # ]:          0 :         if (must_exist && !port) {
    1651                 :          0 :             ctl_fatal("no port or interface named %s", target);
    1652                 :            :         }
    1653                 :            :     }
    1654                 :            : 
    1655         [ +  + ]:         65 :     if (port) {
    1656         [ +  + ]:         63 :         if (ctx->argc == 3) {
    1657                 :            :             struct vsctl_bridge *bridge;
    1658                 :            : 
    1659                 :         50 :             bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1660         [ -  + ]:         50 :             if (port->bridge != bridge) {
    1661         [ #  # ]:          0 :                 if (port->bridge->parent == bridge) {
    1662                 :          0 :                     ctl_fatal("bridge %s does not have a port %s (although "
    1663                 :            :                                 "its parent bridge %s does)",
    1664                 :          0 :                                 ctx->argv[1], ctx->argv[2],
    1665                 :          0 :                                 bridge->parent->name);
    1666                 :            :                 } else {
    1667                 :          0 :                     ctl_fatal("bridge %s does not have a port %s",
    1668                 :          0 :                                 ctx->argv[1], ctx->argv[2]);
    1669                 :            :                 }
    1670                 :            :             }
    1671                 :            :         }
    1672                 :            : 
    1673                 :         63 :         del_port(vsctl_ctx, port);
    1674                 :            :     }
    1675                 :         65 : }
    1676                 :            : 
    1677                 :            : static void
    1678                 :         48 : cmd_port_to_br(struct ctl_context *ctx)
    1679                 :            : {
    1680                 :         48 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1681                 :            :     struct vsctl_port *port;
    1682                 :            : 
    1683                 :         48 :     vsctl_context_populate_cache(ctx);
    1684                 :            : 
    1685                 :         48 :     port = find_port(vsctl_ctx, ctx->argv[1], true);
    1686                 :         22 :     ds_put_format(&ctx->output, "%s\n", port->bridge->name);
    1687                 :         22 : }
    1688                 :            : 
    1689                 :            : static void
    1690                 :         78 : cmd_br_to_vlan(struct ctl_context *ctx)
    1691                 :            : {
    1692                 :         78 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1693                 :            :     struct vsctl_bridge *bridge;
    1694                 :            : 
    1695                 :         78 :     vsctl_context_populate_cache(ctx);
    1696                 :            : 
    1697                 :         78 :     bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1698                 :         78 :     ds_put_format(&ctx->output, "%d\n", bridge->vlan);
    1699                 :         78 : }
    1700                 :            : 
    1701                 :            : static void
    1702                 :         52 : cmd_br_to_parent(struct ctl_context *ctx)
    1703                 :            : {
    1704                 :         52 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1705                 :            :     struct vsctl_bridge *bridge;
    1706                 :            : 
    1707                 :         52 :     vsctl_context_populate_cache(ctx);
    1708                 :            : 
    1709                 :         52 :     bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1710         [ +  + ]:         52 :     if (bridge->parent) {
    1711                 :         10 :         bridge = bridge->parent;
    1712                 :            :     }
    1713                 :         52 :     ds_put_format(&ctx->output, "%s\n", bridge->name);
    1714                 :         52 : }
    1715                 :            : 
    1716                 :            : static void
    1717                 :         41 : cmd_list_ifaces(struct ctl_context *ctx)
    1718                 :            : {
    1719                 :         41 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1720                 :            :     struct vsctl_bridge *br;
    1721                 :            :     struct vsctl_port *port;
    1722                 :            :     struct svec ifaces;
    1723                 :            : 
    1724                 :         41 :     vsctl_context_populate_cache(ctx);
    1725                 :            : 
    1726                 :         41 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1727                 :         41 :     verify_ports(vsctl_ctx);
    1728                 :            : 
    1729                 :         41 :     svec_init(&ifaces);
    1730         [ +  + ]:        124 :     LIST_FOR_EACH (port, ports_node, &br->ports) {
    1731                 :            :         struct vsctl_iface *iface;
    1732                 :            : 
    1733         [ +  + ]:        171 :         LIST_FOR_EACH (iface, ifaces_node, &port->ifaces) {
    1734         [ +  + ]:         88 :             if (strcmp(iface->iface_cfg->name, br->name)) {
    1735                 :         47 :                 svec_add(&ifaces, iface->iface_cfg->name);
    1736                 :            :             }
    1737                 :            :         }
    1738                 :            :     }
    1739                 :         41 :     output_sorted(&ifaces, &ctx->output);
    1740                 :         41 :     svec_destroy(&ifaces);
    1741                 :         41 : }
    1742                 :            : 
    1743                 :            : static void
    1744                 :         64 : cmd_iface_to_br(struct ctl_context *ctx)
    1745                 :            : {
    1746                 :         64 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1747                 :            :     struct vsctl_iface *iface;
    1748                 :            : 
    1749                 :         64 :     vsctl_context_populate_cache(ctx);
    1750                 :            : 
    1751                 :         64 :     iface = find_iface(vsctl_ctx, ctx->argv[1], true);
    1752                 :         39 :     ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
    1753                 :         39 : }
    1754                 :            : 
    1755                 :            : static void
    1756                 :         11 : verify_controllers(struct ovsrec_bridge *bridge)
    1757                 :            : {
    1758                 :            :     size_t i;
    1759                 :            : 
    1760                 :         11 :     ovsrec_bridge_verify_controller(bridge);
    1761         [ +  + ]:         16 :     for (i = 0; i < bridge->n_controller; i++) {
    1762                 :          5 :         ovsrec_controller_verify_target(bridge->controller[i]);
    1763                 :            :     }
    1764                 :         11 : }
    1765                 :            : 
    1766                 :            : static void
    1767                 :         11 : pre_controller(struct ctl_context *ctx)
    1768                 :            : {
    1769                 :         11 :     pre_get_info(ctx);
    1770                 :            : 
    1771                 :         11 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_controller_col_target);
    1772                 :         11 : }
    1773                 :            : 
    1774                 :            : static void
    1775                 :          4 : cmd_get_controller(struct ctl_context *ctx)
    1776                 :            : {
    1777                 :          4 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1778                 :            :     struct vsctl_bridge *br;
    1779                 :            :     struct svec targets;
    1780                 :            :     size_t i;
    1781                 :            : 
    1782                 :          4 :     vsctl_context_populate_cache(ctx);
    1783                 :            : 
    1784                 :          4 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1785         [ -  + ]:          4 :     if (br->parent) {
    1786                 :          0 :         br = br->parent;
    1787                 :            :     }
    1788                 :          4 :     verify_controllers(br->br_cfg);
    1789                 :            : 
    1790                 :            :     /* Print the targets in sorted order for reproducibility. */
    1791                 :          4 :     svec_init(&targets);
    1792         [ +  + ]:          7 :     for (i = 0; i < br->br_cfg->n_controller; i++) {
    1793                 :          3 :         svec_add(&targets, br->br_cfg->controller[i]->target);
    1794                 :            :     }
    1795                 :            : 
    1796                 :          4 :     svec_sort(&targets);
    1797         [ +  + ]:          7 :     for (i = 0; i < targets.n; i++) {
    1798                 :          3 :         ds_put_format(&ctx->output, "%s\n", targets.names[i]);
    1799                 :            :     }
    1800                 :          4 :     svec_destroy(&targets);
    1801                 :          4 : }
    1802                 :            : 
    1803                 :            : static void
    1804                 :          7 : delete_controllers(struct ovsrec_controller **controllers,
    1805                 :            :                    size_t n_controllers)
    1806                 :            : {
    1807                 :            :     size_t i;
    1808                 :            : 
    1809         [ +  + ]:          9 :     for (i = 0; i < n_controllers; i++) {
    1810                 :          2 :         ovsrec_controller_delete(controllers[i]);
    1811                 :            :     }
    1812                 :          7 : }
    1813                 :            : 
    1814                 :            : static void
    1815                 :          1 : cmd_del_controller(struct ctl_context *ctx)
    1816                 :            : {
    1817                 :          1 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1818                 :            :     struct ovsrec_bridge *br;
    1819                 :            : 
    1820                 :          1 :     vsctl_context_populate_cache(ctx);
    1821                 :            : 
    1822                 :          1 :     br = find_real_bridge(vsctl_ctx, ctx->argv[1], true)->br_cfg;
    1823                 :          1 :     verify_controllers(br);
    1824                 :            : 
    1825         [ +  - ]:          1 :     if (br->controller) {
    1826                 :          1 :         delete_controllers(br->controller, br->n_controller);
    1827                 :          1 :         ovsrec_bridge_set_controller(br, NULL, 0);
    1828                 :            :     }
    1829                 :          1 : }
    1830                 :            : 
    1831                 :            : static struct ovsrec_controller **
    1832                 :          6 : insert_controllers(struct ovsdb_idl_txn *txn, char *targets[], size_t n)
    1833                 :            : {
    1834                 :            :     struct ovsrec_controller **controllers;
    1835                 :            :     size_t i;
    1836                 :            : 
    1837                 :          6 :     controllers = xmalloc(n * sizeof *controllers);
    1838         [ +  + ]:         13 :     for (i = 0; i < n; i++) {
    1839 [ +  + ][ -  + ]:          7 :         if (vconn_verify_name(targets[i]) && pvconn_verify_name(targets[i])) {
    1840         [ #  # ]:          0 :             VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
    1841                 :            :         }
    1842                 :          7 :         controllers[i] = ovsrec_controller_insert(txn);
    1843                 :          7 :         ovsrec_controller_set_target(controllers[i], targets[i]);
    1844                 :            :     }
    1845                 :            : 
    1846                 :          6 :     return controllers;
    1847                 :            : }
    1848                 :            : 
    1849                 :            : static void
    1850                 :          6 : cmd_set_controller(struct ctl_context *ctx)
    1851                 :            : {
    1852                 :          6 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1853                 :            :     struct ovsrec_controller **controllers;
    1854                 :            :     struct ovsrec_bridge *br;
    1855                 :            :     size_t n;
    1856                 :            : 
    1857                 :          6 :     vsctl_context_populate_cache(ctx);
    1858                 :            : 
    1859                 :          6 :     br = find_real_bridge(vsctl_ctx, ctx->argv[1], true)->br_cfg;
    1860                 :          6 :     verify_controllers(br);
    1861                 :            : 
    1862                 :          6 :     delete_controllers(br->controller, br->n_controller);
    1863                 :            : 
    1864                 :          6 :     n = ctx->argc - 2;
    1865                 :          6 :     controllers = insert_controllers(ctx->txn, &ctx->argv[2], n);
    1866                 :          6 :     ovsrec_bridge_set_controller(br, controllers, n);
    1867                 :          6 :     free(controllers);
    1868                 :          6 : }
    1869                 :            : 
    1870                 :            : static void
    1871                 :          0 : cmd_get_fail_mode(struct ctl_context *ctx)
    1872                 :            : {
    1873                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1874                 :            :     struct vsctl_bridge *br;
    1875                 :            :     const char *fail_mode;
    1876                 :            : 
    1877                 :          0 :     vsctl_context_populate_cache(ctx);
    1878                 :          0 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    1879                 :            : 
    1880         [ #  # ]:          0 :     if (br->parent) {
    1881                 :          0 :         br = br->parent;
    1882                 :            :     }
    1883                 :          0 :     ovsrec_bridge_verify_fail_mode(br->br_cfg);
    1884                 :            : 
    1885                 :          0 :     fail_mode = br->br_cfg->fail_mode;
    1886 [ #  # ][ #  # ]:          0 :     if (fail_mode && strlen(fail_mode)) {
    1887                 :          0 :         ds_put_format(&ctx->output, "%s\n", fail_mode);
    1888                 :            :     }
    1889                 :          0 : }
    1890                 :            : 
    1891                 :            : static void
    1892                 :          0 : cmd_del_fail_mode(struct ctl_context *ctx)
    1893                 :            : {
    1894                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1895                 :            :     struct vsctl_bridge *br;
    1896                 :            : 
    1897                 :          0 :     vsctl_context_populate_cache(ctx);
    1898                 :            : 
    1899                 :          0 :     br = find_real_bridge(vsctl_ctx, ctx->argv[1], true);
    1900                 :            : 
    1901                 :          0 :     ovsrec_bridge_set_fail_mode(br->br_cfg, NULL);
    1902                 :          0 : }
    1903                 :            : 
    1904                 :            : static void
    1905                 :          3 : cmd_set_fail_mode(struct ctl_context *ctx)
    1906                 :            : {
    1907                 :          3 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1908                 :            :     struct vsctl_bridge *br;
    1909                 :          3 :     const char *fail_mode = ctx->argv[2];
    1910                 :            : 
    1911                 :          3 :     vsctl_context_populate_cache(ctx);
    1912                 :            : 
    1913                 :          3 :     br = find_real_bridge(vsctl_ctx, ctx->argv[1], true);
    1914                 :            : 
    1915 [ +  - ][ -  + ]:          3 :     if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
    1916                 :          0 :         ctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
    1917                 :            :     }
    1918                 :            : 
    1919                 :          3 :     ovsrec_bridge_set_fail_mode(br->br_cfg, fail_mode);
    1920                 :          3 : }
    1921                 :            : 
    1922                 :            : static void
    1923                 :         59 : verify_managers(const struct ovsrec_open_vswitch *ovs)
    1924                 :            : {
    1925                 :            :     size_t i;
    1926                 :            : 
    1927                 :         59 :     ovsrec_open_vswitch_verify_manager_options(ovs);
    1928                 :            : 
    1929         [ +  + ]:         65 :     for (i = 0; i < ovs->n_manager_options; ++i) {
    1930                 :          6 :         const struct ovsrec_manager *mgr = ovs->manager_options[i];
    1931                 :            : 
    1932                 :          6 :         ovsrec_manager_verify_target(mgr);
    1933                 :            :     }
    1934                 :         59 : }
    1935                 :            : 
    1936                 :            : static void
    1937                 :         61 : pre_manager(struct ctl_context *ctx)
    1938                 :            : {
    1939                 :         61 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
    1940                 :         61 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_manager_col_target);
    1941                 :         61 : }
    1942                 :            : 
    1943                 :            : static void
    1944                 :         55 : cmd_get_manager(struct ctl_context *ctx)
    1945                 :            : {
    1946                 :         55 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1947                 :         55 :     const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
    1948                 :            :     struct svec targets;
    1949                 :            :     size_t i;
    1950                 :            : 
    1951                 :         55 :     verify_managers(ovs);
    1952                 :            : 
    1953                 :            :     /* Print the targets in sorted order for reproducibility. */
    1954                 :         55 :     svec_init(&targets);
    1955                 :            : 
    1956         [ +  + ]:         58 :     for (i = 0; i < ovs->n_manager_options; i++) {
    1957                 :          3 :         svec_add(&targets, ovs->manager_options[i]->target);
    1958                 :            :     }
    1959                 :            : 
    1960                 :         55 :     svec_sort_unique(&targets);
    1961         [ +  + ]:         58 :     for (i = 0; i < targets.n; i++) {
    1962                 :          3 :         ds_put_format(&ctx->output, "%s\n", targets.names[i]);
    1963                 :            :     }
    1964                 :         55 :     svec_destroy(&targets);
    1965                 :         55 : }
    1966                 :            : 
    1967                 :            : static void
    1968                 :          4 : delete_managers(const struct ovsrec_open_vswitch *ovs)
    1969                 :            : {
    1970                 :            :     size_t i;
    1971                 :            : 
    1972                 :            :     /* Delete Manager rows pointed to by 'manager_options' column. */
    1973         [ +  + ]:          7 :     for (i = 0; i < ovs->n_manager_options; i++) {
    1974                 :          3 :         ovsrec_manager_delete(ovs->manager_options[i]);
    1975                 :            :     }
    1976                 :            : 
    1977                 :            :     /* Delete 'Manager' row refs in 'manager_options' column. */
    1978                 :          4 :     ovsrec_open_vswitch_set_manager_options(ovs, NULL, 0);
    1979                 :          4 : }
    1980                 :            : 
    1981                 :            : static void
    1982                 :          2 : cmd_del_manager(struct ctl_context *ctx)
    1983                 :            : {
    1984                 :          2 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    1985                 :          2 :     const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
    1986                 :            : 
    1987                 :          2 :     verify_managers(ovs);
    1988                 :          2 :     delete_managers(ovs);
    1989                 :          2 : }
    1990                 :            : 
    1991                 :            : static void
    1992                 :          2 : insert_managers(struct vsctl_context *vsctl_ctx, char *targets[], size_t n)
    1993                 :            : {
    1994                 :            :     struct ovsrec_manager **managers;
    1995                 :            :     size_t i;
    1996                 :            : 
    1997                 :            :     /* Insert each manager in a new row in Manager table. */
    1998                 :          2 :     managers = xmalloc(n * sizeof *managers);
    1999         [ +  + ]:          5 :     for (i = 0; i < n; i++) {
    2000 [ -  + ][ #  # ]:          3 :         if (stream_verify_name(targets[i]) && pstream_verify_name(targets[i])) {
    2001         [ #  # ]:          0 :             VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
    2002                 :            :         }
    2003                 :          3 :         managers[i] = ovsrec_manager_insert(vsctl_ctx->base.txn);
    2004                 :          3 :         ovsrec_manager_set_target(managers[i], targets[i]);
    2005                 :            :     }
    2006                 :            : 
    2007                 :            :     /* Store uuids of new Manager rows in 'manager_options' column. */
    2008                 :          2 :     ovsrec_open_vswitch_set_manager_options(vsctl_ctx->ovs, managers, n);
    2009                 :          2 :     free(managers);
    2010                 :          2 : }
    2011                 :            : 
    2012                 :            : static void
    2013                 :          2 : cmd_set_manager(struct ctl_context *ctx)
    2014                 :            : {
    2015                 :          2 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2016                 :          2 :     const size_t n = ctx->argc - 1;
    2017                 :            : 
    2018                 :          2 :     verify_managers(vsctl_ctx->ovs);
    2019                 :          2 :     delete_managers(vsctl_ctx->ovs);
    2020                 :          2 :     insert_managers(vsctl_ctx, &ctx->argv[1], n);
    2021                 :          2 : }
    2022                 :            : 
    2023                 :            : static void
    2024                 :          0 : pre_cmd_get_ssl(struct ctl_context *ctx)
    2025                 :            : {
    2026                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
    2027                 :            : 
    2028                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_private_key);
    2029                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_certificate);
    2030                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_ca_cert);
    2031                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_bootstrap_ca_cert);
    2032                 :          0 : }
    2033                 :            : 
    2034                 :            : static void
    2035                 :          0 : cmd_get_ssl(struct ctl_context *ctx)
    2036                 :            : {
    2037                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2038                 :          0 :     struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
    2039                 :            : 
    2040                 :          0 :     ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
    2041         [ #  # ]:          0 :     if (ssl) {
    2042                 :          0 :         ovsrec_ssl_verify_private_key(ssl);
    2043                 :          0 :         ovsrec_ssl_verify_certificate(ssl);
    2044                 :          0 :         ovsrec_ssl_verify_ca_cert(ssl);
    2045                 :          0 :         ovsrec_ssl_verify_bootstrap_ca_cert(ssl);
    2046                 :            : 
    2047                 :          0 :         ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
    2048                 :          0 :         ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
    2049                 :          0 :         ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
    2050         [ #  # ]:          0 :         ds_put_format(&ctx->output, "Bootstrap: %s\n",
    2051                 :          0 :                 ssl->bootstrap_ca_cert ? "true" : "false");
    2052                 :            :     }
    2053                 :          0 : }
    2054                 :            : 
    2055                 :            : static void
    2056                 :          0 : pre_cmd_del_ssl(struct ctl_context *ctx)
    2057                 :            : {
    2058                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
    2059                 :          0 : }
    2060                 :            : 
    2061                 :            : static void
    2062                 :          0 : cmd_del_ssl(struct ctl_context *ctx)
    2063                 :            : {
    2064                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2065                 :          0 :     struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
    2066                 :            : 
    2067         [ #  # ]:          0 :     if (ssl) {
    2068                 :          0 :         ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
    2069                 :          0 :         ovsrec_ssl_delete(ssl);
    2070                 :          0 :         ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
    2071                 :            :     }
    2072                 :          0 : }
    2073                 :            : 
    2074                 :            : static void
    2075                 :          1 : pre_cmd_set_ssl(struct ctl_context *ctx)
    2076                 :            : {
    2077                 :          1 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
    2078                 :          1 : }
    2079                 :            : 
    2080                 :            : static void
    2081                 :          1 : cmd_set_ssl(struct ctl_context *ctx)
    2082                 :            : {
    2083                 :          1 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2084                 :          1 :     bool bootstrap = shash_find(&ctx->options, "--bootstrap");
    2085                 :          1 :     struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
    2086                 :            : 
    2087                 :          1 :     ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
    2088         [ -  + ]:          1 :     if (ssl) {
    2089                 :          0 :         ovsrec_ssl_delete(ssl);
    2090                 :            :     }
    2091                 :          1 :     ssl = ovsrec_ssl_insert(ctx->txn);
    2092                 :            : 
    2093                 :          1 :     ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
    2094                 :          1 :     ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
    2095                 :          1 :     ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
    2096                 :            : 
    2097                 :          1 :     ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
    2098                 :            : 
    2099                 :          1 :     ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, ssl);
    2100                 :          1 : }
    2101                 :            : 
    2102                 :            : static void
    2103                 :          0 : autoattach_insert_mapping(struct ovsrec_autoattach *aa,
    2104                 :            :                           int64_t isid,
    2105                 :            :                           int64_t vlan)
    2106                 :            : {
    2107                 :            :     int64_t *key_mappings, *value_mappings;
    2108                 :            :     size_t i;
    2109                 :            : 
    2110                 :          0 :     key_mappings = xmalloc(sizeof *aa->key_mappings * (aa->n_mappings + 1));
    2111                 :          0 :     value_mappings = xmalloc(sizeof *aa->value_mappings * (aa->n_mappings + 1));
    2112                 :            : 
    2113         [ #  # ]:          0 :     for (i = 0; i < aa->n_mappings; i++) {
    2114                 :          0 :         key_mappings[i] = aa->key_mappings[i];
    2115                 :          0 :         value_mappings[i] = aa->value_mappings[i];
    2116                 :            :     }
    2117                 :          0 :     key_mappings[aa->n_mappings] = isid;
    2118                 :          0 :     value_mappings[aa->n_mappings] = vlan;
    2119                 :            : 
    2120                 :          0 :     ovsrec_autoattach_set_mappings(aa, key_mappings, value_mappings,
    2121                 :          0 :                                    aa->n_mappings + 1);
    2122                 :            : 
    2123                 :          0 :     free(key_mappings);
    2124                 :          0 :     free(value_mappings);
    2125                 :          0 : }
    2126                 :            : 
    2127                 :            : static void
    2128                 :          0 : cmd_add_aa_mapping(struct ctl_context *ctx)
    2129                 :            : {
    2130                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2131                 :            :     struct vsctl_bridge *br;
    2132                 :            :     int64_t isid, vlan;
    2133                 :          0 :     char *nptr = NULL;
    2134                 :            : 
    2135                 :          0 :     isid = strtoull(ctx->argv[2], &nptr, 10);
    2136 [ #  # ][ #  # ]:          0 :     if (nptr == ctx->argv[2] || nptr == NULL) {
    2137                 :          0 :         ctl_fatal("Invalid argument %s", ctx->argv[2]);
    2138                 :            :         return;
    2139                 :            :     }
    2140                 :            : 
    2141                 :          0 :     vlan = strtoull(ctx->argv[3], &nptr, 10);
    2142 [ #  # ][ #  # ]:          0 :     if (nptr == ctx->argv[3] || nptr == NULL) {
    2143                 :          0 :         ctl_fatal("Invalid argument %s", ctx->argv[3]);
    2144                 :            :         return;
    2145                 :            :     }
    2146                 :            : 
    2147                 :          0 :     vsctl_context_populate_cache(ctx);
    2148                 :            : 
    2149                 :          0 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    2150         [ #  # ]:          0 :     if (br->parent) {
    2151                 :          0 :         br = br->parent;
    2152                 :            :     }
    2153                 :            : 
    2154         [ #  # ]:          0 :     if (br->br_cfg) {
    2155         [ #  # ]:          0 :         if (!br->br_cfg->auto_attach) {
    2156                 :          0 :             struct ovsrec_autoattach *aa = ovsrec_autoattach_insert(ctx->txn);
    2157                 :          0 :             ovsrec_bridge_set_auto_attach(br->br_cfg, aa);
    2158                 :            :         }
    2159                 :          0 :         autoattach_insert_mapping(br->br_cfg->auto_attach, isid, vlan);
    2160                 :            :     }
    2161                 :          0 : }
    2162                 :            : 
    2163                 :            : static void
    2164                 :          0 : del_aa_mapping(struct ovsrec_autoattach *aa,
    2165                 :            :                int64_t isid,
    2166                 :            :                int64_t vlan)
    2167                 :            : {
    2168                 :            :     int64_t *key_mappings, *value_mappings;
    2169                 :            :     size_t i, n;
    2170                 :            : 
    2171                 :          0 :     key_mappings = xmalloc(sizeof *aa->key_mappings * (aa->n_mappings));
    2172                 :          0 :     value_mappings = xmalloc(sizeof *value_mappings * (aa->n_mappings));
    2173                 :            : 
    2174         [ #  # ]:          0 :     for (i = n = 0; i < aa->n_mappings; i++) {
    2175 [ #  # ][ #  # ]:          0 :         if (aa->key_mappings[i] != isid && aa->value_mappings[i] != vlan) {
    2176                 :          0 :             key_mappings[n] = aa->key_mappings[i];
    2177                 :          0 :             value_mappings[n++] = aa->value_mappings[i];
    2178                 :            :         }
    2179                 :            :     }
    2180                 :            : 
    2181                 :          0 :     ovsrec_autoattach_set_mappings(aa, key_mappings, value_mappings, n);
    2182                 :            : 
    2183                 :          0 :     free(key_mappings);
    2184                 :          0 :     free(value_mappings);
    2185                 :          0 : }
    2186                 :            : 
    2187                 :            : static void
    2188                 :          0 : cmd_del_aa_mapping(struct ctl_context *ctx)
    2189                 :            : {
    2190                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2191                 :            :     struct vsctl_bridge *br;
    2192                 :            :     int64_t isid, vlan;
    2193                 :          0 :     char *nptr = NULL;
    2194                 :            : 
    2195                 :          0 :     isid = strtoull(ctx->argv[2], &nptr, 10);
    2196 [ #  # ][ #  # ]:          0 :     if (nptr == ctx->argv[2] || nptr == NULL) {
    2197                 :          0 :         ctl_fatal("Invalid argument %s", ctx->argv[2]);
    2198                 :            :         return;
    2199                 :            :     }
    2200                 :            : 
    2201                 :          0 :     vlan = strtoull(ctx->argv[3], &nptr, 10);
    2202 [ #  # ][ #  # ]:          0 :     if (nptr == ctx->argv[3] || nptr == NULL) {
    2203                 :          0 :         ctl_fatal("Invalid argument %s", ctx->argv[3]);
    2204                 :            :         return;
    2205                 :            :     }
    2206                 :            : 
    2207                 :          0 :     vsctl_context_populate_cache(ctx);
    2208                 :            : 
    2209                 :          0 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    2210         [ #  # ]:          0 :     if (br->parent) {
    2211                 :          0 :         br = br->parent;
    2212                 :            :     }
    2213                 :            : 
    2214 [ #  # ][ #  # ]:          0 :     if (br->br_cfg && br->br_cfg->auto_attach &&
                 [ #  # ]
    2215         [ #  # ]:          0 :         br->br_cfg->auto_attach->key_mappings &&
    2216                 :          0 :         br->br_cfg->auto_attach->value_mappings) {
    2217                 :            :         size_t i;
    2218                 :            : 
    2219         [ #  # ]:          0 :         for (i = 0; i < br->br_cfg->auto_attach->n_mappings; i++) {
    2220 [ #  # ][ #  # ]:          0 :             if (br->br_cfg->auto_attach->key_mappings[i] == isid &&
    2221                 :          0 :                 br->br_cfg->auto_attach->value_mappings[i] == vlan) {
    2222                 :          0 :                 del_aa_mapping(br->br_cfg->auto_attach, isid, vlan);
    2223                 :          0 :                 break;
    2224                 :            :             }
    2225                 :            :         }
    2226                 :            :     }
    2227                 :          0 : }
    2228                 :            : 
    2229                 :            : static void
    2230                 :          0 : pre_aa_mapping(struct ctl_context *ctx)
    2231                 :            : {
    2232                 :          0 :     pre_get_info(ctx);
    2233                 :            : 
    2234                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_auto_attach);
    2235                 :          0 :     ovsdb_idl_add_column(ctx->idl, &ovsrec_autoattach_col_mappings);
    2236                 :          0 : }
    2237                 :            : 
    2238                 :            : static void
    2239                 :          0 : verify_auto_attach(struct ovsrec_bridge *bridge)
    2240                 :            : {
    2241         [ #  # ]:          0 :     if (bridge) {
    2242                 :          0 :         ovsrec_bridge_verify_auto_attach(bridge);
    2243                 :            : 
    2244         [ #  # ]:          0 :         if (bridge->auto_attach) {
    2245                 :          0 :             ovsrec_autoattach_verify_mappings(bridge->auto_attach);
    2246                 :            :         }
    2247                 :            :     }
    2248                 :          0 : }
    2249                 :            : 
    2250                 :            : static void
    2251                 :          0 : cmd_get_aa_mapping(struct ctl_context *ctx)
    2252                 :            : {
    2253                 :          0 :     struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    2254                 :            :     struct vsctl_bridge *br;
    2255                 :            : 
    2256                 :          0 :     vsctl_context_populate_cache(ctx);
    2257                 :            : 
    2258                 :          0 :     br = find_bridge(vsctl_ctx, ctx->argv[1], true);
    2259         [ #  # ]:          0 :     if (br->parent) {
    2260                 :          0 :         br = br->parent;
    2261                 :            :     }
    2262                 :            : 
    2263                 :          0 :     verify_auto_attach(br->br_cfg);
    2264                 :            : 
    2265 [ #  # ][ #  # ]:          0 :     if (br->br_cfg && br->br_cfg->auto_attach &&
                 [ #  # ]
    2266         [ #  # ]:          0 :         br->br_cfg->auto_attach->key_mappings &&
    2267                 :          0 :         br->br_cfg->auto_attach->value_mappings) {
    2268                 :            :         size_t i;
    2269                 :            : 
    2270         [ #  # ]:          0 :         for (i = 0; i < br->br_cfg->auto_attach->n_mappings; i++) {
    2271                 :          0 :             ds_put_format(&ctx->output, "%"PRId64" %"PRId64"\n",
    2272                 :          0 :                           br->br_cfg->auto_attach->key_mappings[i],
    2273                 :          0 :                           br->br_cfg->auto_attach->value_mappings[i]);
    2274                 :            :         }
    2275                 :            :     }
    2276                 :          0 : }
    2277                 :            : 
    2278                 :            : 
    2279                 :            : static const struct ctl_table_class tables[] = {
    2280                 :            :     {&ovsrec_table_bridge,
    2281                 :            :      {{&ovsrec_table_bridge, &ovsrec_bridge_col_name, NULL},
    2282                 :            :       {&ovsrec_table_flow_sample_collector_set, NULL,
    2283                 :            :        &ovsrec_flow_sample_collector_set_col_bridge}}},
    2284                 :            : 
    2285                 :            :     {&ovsrec_table_controller,
    2286                 :            :      {{&ovsrec_table_bridge,
    2287                 :            :        &ovsrec_bridge_col_name,
    2288                 :            :        &ovsrec_bridge_col_controller}}},
    2289                 :            : 
    2290                 :            :     {&ovsrec_table_interface,
    2291                 :            :      {{&ovsrec_table_interface, &ovsrec_interface_col_name, NULL},
    2292                 :            :       {NULL, NULL, NULL}}},
    2293                 :            : 
    2294                 :            :     {&ovsrec_table_mirror,
    2295                 :            :      {{&ovsrec_table_mirror, &ovsrec_mirror_col_name, NULL},
    2296                 :            :       {NULL, NULL, NULL}}},
    2297                 :            : 
    2298                 :            :     {&ovsrec_table_manager,
    2299                 :            :      {{&ovsrec_table_manager, &ovsrec_manager_col_target, NULL},
    2300                 :            :       {NULL, NULL, NULL}}},
    2301                 :            : 
    2302                 :            :     {&ovsrec_table_netflow,
    2303                 :            :      {{&ovsrec_table_bridge,
    2304                 :            :        &ovsrec_bridge_col_name,
    2305                 :            :        &ovsrec_bridge_col_netflow},
    2306                 :            :       {NULL, NULL, NULL}}},
    2307                 :            : 
    2308                 :            :     {&ovsrec_table_open_vswitch,
    2309                 :            :      {{&ovsrec_table_open_vswitch, NULL, NULL},
    2310                 :            :       {NULL, NULL, NULL}}},
    2311                 :            : 
    2312                 :            :     {&ovsrec_table_port,
    2313                 :            :      {{&ovsrec_table_port, &ovsrec_port_col_name, NULL},
    2314                 :            :       {NULL, NULL, NULL}}},
    2315                 :            : 
    2316                 :            :     {&ovsrec_table_qos,
    2317                 :            :      {{&ovsrec_table_port, &ovsrec_port_col_name, &ovsrec_port_col_qos},
    2318                 :            :       {NULL, NULL, NULL}}},
    2319                 :            : 
    2320                 :            :     {&ovsrec_table_queue,
    2321                 :            :      {{NULL, NULL, NULL},
    2322                 :            :       {NULL, NULL, NULL}}},
    2323                 :            : 
    2324                 :            :     {&ovsrec_table_ssl,
    2325                 :            :      {{&ovsrec_table_open_vswitch, NULL, &ovsrec_open_vswitch_col_ssl}}},
    2326                 :            : 
    2327                 :            :     {&ovsrec_table_sflow,
    2328                 :            :      {{&ovsrec_table_bridge,
    2329                 :            :        &ovsrec_bridge_col_name,
    2330                 :            :        &ovsrec_bridge_col_sflow},
    2331                 :            :       {NULL, NULL, NULL}}},
    2332                 :            : 
    2333                 :            :     {&ovsrec_table_flow_table,
    2334                 :            :      {{&ovsrec_table_flow_table, &ovsrec_flow_table_col_name, NULL},
    2335                 :            :       {NULL, NULL, NULL}}},
    2336                 :            : 
    2337                 :            :     {&ovsrec_table_ipfix,
    2338                 :            :      {{&ovsrec_table_bridge,
    2339                 :            :        &ovsrec_bridge_col_name,
    2340                 :            :        &ovsrec_bridge_col_ipfix},
    2341                 :            :       {&ovsrec_table_flow_sample_collector_set, NULL,
    2342                 :            :        &ovsrec_flow_sample_collector_set_col_ipfix}}},
    2343                 :            : 
    2344                 :            :     {&ovsrec_table_autoattach,
    2345                 :            :      {{&ovsrec_table_bridge,
    2346                 :            :        &ovsrec_bridge_col_name,
    2347                 :            :        &ovsrec_bridge_col_auto_attach},
    2348                 :            :       {NULL, NULL, NULL}}},
    2349                 :            : 
    2350                 :            :     {&ovsrec_table_flow_sample_collector_set,
    2351                 :            :      {{&ovsrec_table_flow_sample_collector_set,
    2352                 :            :        &ovsrec_flow_sample_collector_set_col_id,
    2353                 :            :        NULL},
    2354                 :            :       {NULL, NULL, NULL}}},
    2355                 :            : 
    2356                 :            :     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
    2357                 :            : };
    2358                 :            : 
    2359                 :            : static void
    2360                 :       4526 : post_db_reload_check_init(void)
    2361                 :            : {
    2362                 :       4526 :     n_neoteric_ifaces = 0;
    2363                 :       4526 : }
    2364                 :            : 
    2365                 :            : static void
    2366                 :       3692 : post_db_reload_expect_iface(const struct ovsrec_interface *iface)
    2367                 :            : {
    2368         [ +  + ]:       3692 :     if (n_neoteric_ifaces >= allocated_neoteric_ifaces) {
    2369                 :       2330 :         neoteric_ifaces = x2nrealloc(neoteric_ifaces,
    2370                 :            :                                      &allocated_neoteric_ifaces,
    2371                 :            :                                      sizeof *neoteric_ifaces);
    2372                 :            :     }
    2373                 :       3692 :     neoteric_ifaces[n_neoteric_ifaces++] = iface->header_.uuid;
    2374                 :       3692 : }
    2375                 :            : 
    2376                 :            : static void
    2377                 :       2150 : post_db_reload_do_checks(const struct vsctl_context *vsctl_ctx)
    2378                 :            : {
    2379                 :       2150 :     struct ds dead_ifaces = DS_EMPTY_INITIALIZER;
    2380                 :            :     size_t i;
    2381                 :            : 
    2382         [ +  + ]:       4409 :     for (i = 0; i < n_neoteric_ifaces; i++) {
    2383                 :            :         const struct uuid *uuid;
    2384                 :            : 
    2385                 :       2259 :         uuid = ovsdb_idl_txn_get_insert_uuid(vsctl_ctx->base.txn,
    2386                 :       2259 :                                              &neoteric_ifaces[i]);
    2387         [ +  - ]:       2259 :         if (uuid) {
    2388                 :            :             const struct ovsrec_interface *iface;
    2389                 :            : 
    2390                 :       2259 :             iface = ovsrec_interface_get_for_uuid(vsctl_ctx->base.idl, uuid);
    2391 [ +  - ][ +  + ]:       2259 :             if (iface && (!iface->ofport || *iface->ofport == -1)) {
                 [ +  + ]
    2392                 :         11 :                 ds_put_format(&dead_ifaces, "'%s', ", iface->name);
    2393                 :            :             }
    2394                 :            :         }
    2395                 :            :     }
    2396                 :            : 
    2397         [ +  + ]:       2150 :     if (dead_ifaces.length) {
    2398                 :         11 :         dead_ifaces.length -= 2; /* Strip off trailing comma and space. */
    2399                 :         11 :         ovs_error(0, "Error detected while setting up %s.  See ovs-vswitchd "
    2400                 :            :                   "log for details.", ds_cstr(&dead_ifaces));
    2401                 :            :     }
    2402                 :            : 
    2403                 :       2150 :     ds_destroy(&dead_ifaces);
    2404                 :       2150 : }
    2405                 :            : 
    2406                 :            : 
    2407                 :            : static void
    2408                 :       9651 : vsctl_context_init_command(struct vsctl_context *vsctl_ctx,
    2409                 :            :                            struct ctl_command *command)
    2410                 :            : {
    2411                 :       9651 :     ctl_context_init_command(&vsctl_ctx->base, command);
    2412                 :       9651 :     vsctl_ctx->verified_ports = false;
    2413                 :       9651 : }
    2414                 :            : 
    2415                 :            : static void
    2416                 :      13633 : vsctl_context_init(struct vsctl_context *vsctl_ctx,
    2417                 :            :                    struct ctl_command *command, struct ovsdb_idl *idl,
    2418                 :            :                    struct ovsdb_idl_txn *txn,
    2419                 :            :                    const struct ovsrec_open_vswitch *ovs,
    2420                 :            :                    struct ovsdb_symbol_table *symtab)
    2421                 :            : {
    2422                 :      13633 :     ctl_context_init(&vsctl_ctx->base, command, idl, txn, symtab,
    2423                 :            :                      vsctl_context_invalidate_cache);
    2424         [ +  + ]:      13633 :     if (command) {
    2425                 :       9107 :         vsctl_ctx->verified_ports = false;
    2426                 :            :     }
    2427                 :      13633 :     vsctl_ctx->ovs = ovs;
    2428                 :      13633 :     vsctl_ctx->cache_valid = false;
    2429                 :      13633 : }
    2430                 :            : 
    2431                 :            : static void
    2432                 :       9531 : vsctl_context_done_command(struct vsctl_context *vsctl_ctx,
    2433                 :            :                            struct ctl_command *command)
    2434                 :            : {
    2435                 :       9531 :     ctl_context_done_command(&vsctl_ctx->base, command);
    2436                 :       9531 : }
    2437                 :            : 
    2438                 :            : static void
    2439                 :      13507 : vsctl_context_done(struct vsctl_context *vsctl_ctx,
    2440                 :            :                    struct ctl_command *command)
    2441                 :            : {
    2442                 :      13507 :     ctl_context_done(&vsctl_ctx->base, command);
    2443                 :      13507 : }
    2444                 :            : 
    2445                 :            : static void
    2446                 :       4530 : run_prerequisites(struct ctl_command *commands, size_t n_commands,
    2447                 :            :                   struct ovsdb_idl *idl)
    2448                 :            : {
    2449                 :            :     struct ctl_command *c;
    2450                 :            : 
    2451                 :       4530 :     ovsdb_idl_add_table(idl, &ovsrec_table_open_vswitch);
    2452         [ +  + ]:       4530 :     if (wait_for_reload) {
    2453                 :       3137 :         ovsdb_idl_add_column(idl, &ovsrec_open_vswitch_col_cur_cfg);
    2454                 :            :     }
    2455         [ +  + ]:      14179 :     for (c = commands; c < &commands[n_commands]; c++) {
    2456         [ +  + ]:       9655 :         if (c->syntax->prerequisites) {
    2457                 :            :             struct vsctl_context vsctl_ctx;
    2458                 :            : 
    2459                 :       9027 :             ds_init(&c->output);
    2460                 :       9027 :             c->table = NULL;
    2461                 :            : 
    2462                 :       9027 :             vsctl_context_init(&vsctl_ctx, c, idl, NULL, NULL, NULL);
    2463                 :       9027 :             (c->syntax->prerequisites)(&vsctl_ctx.base);
    2464                 :       9021 :             vsctl_context_done(&vsctl_ctx, c);
    2465                 :            : 
    2466         [ -  + ]:       9021 :             ovs_assert(!c->output.string);
    2467         [ -  + ]:       9021 :             ovs_assert(!c->table);
    2468                 :            :         }
    2469                 :            :     }
    2470                 :       4524 : }
    2471                 :            : 
    2472                 :            : static char *
    2473                 :       4526 : vsctl_parent_process_info(void)
    2474                 :            : {
    2475                 :            : #ifdef __linux__
    2476                 :            :     pid_t parent_pid;
    2477                 :            :     struct ds s;
    2478                 :            : 
    2479                 :       4526 :     parent_pid = getppid();
    2480                 :       4526 :     ds_init(&s);
    2481                 :            : 
    2482                 :            :     /* Retrive the command line of the parent process, except the init
    2483                 :            :      * process since /proc/0 does not exist. */
    2484         [ +  - ]:       4526 :     if (parent_pid) {
    2485                 :            :         char *procfile;
    2486                 :            :         FILE *f;
    2487                 :            : 
    2488                 :       4526 :         procfile = xasprintf("/proc/%d/cmdline", parent_pid);
    2489                 :            : 
    2490                 :       4526 :         f = fopen(procfile, "r");
    2491                 :       4526 :         free(procfile);
    2492         [ +  - ]:       4526 :         if (f) {
    2493                 :       4526 :             ds_get_line(&s, f);
    2494                 :       4526 :             fclose(f);
    2495                 :            :         }
    2496                 :            :     } else {
    2497                 :          0 :         ds_put_cstr(&s, "init");
    2498                 :            :     }
    2499                 :            : 
    2500                 :       4526 :     ds_put_format(&s, " (pid %d)", parent_pid);
    2501                 :       4526 :     return ds_steal_cstr(&s);
    2502                 :            : #else
    2503                 :            :     return NULL;
    2504                 :            : #endif
    2505                 :            : }
    2506                 :            : 
    2507                 :            : static void
    2508                 :       4526 : do_vsctl(const char *args, struct ctl_command *commands, size_t n_commands,
    2509                 :            :          struct ovsdb_idl *idl)
    2510                 :            : {
    2511                 :            :     struct ovsdb_idl_txn *txn;
    2512                 :            :     const struct ovsrec_open_vswitch *ovs;
    2513                 :            :     enum ovsdb_idl_txn_status status;
    2514                 :            :     struct ovsdb_symbol_table *symtab;
    2515                 :            :     struct vsctl_context vsctl_ctx;
    2516                 :            :     struct ctl_command *c;
    2517                 :            :     struct shash_node *node;
    2518                 :       4526 :     int64_t next_cfg = 0;
    2519                 :       4526 :     char *error = NULL;
    2520                 :       4526 :     char *ppid_info = NULL;
    2521                 :            : 
    2522                 :       4526 :     txn = the_idl_txn = ovsdb_idl_txn_create(idl);
    2523         [ -  + ]:       4526 :     if (dry_run) {
    2524                 :          0 :         ovsdb_idl_txn_set_dry_run(txn);
    2525                 :            :     }
    2526                 :            : 
    2527                 :       4526 :     ppid_info = vsctl_parent_process_info();
    2528         [ +  - ]:       4526 :     if (ppid_info) {
    2529                 :       4526 :         ovsdb_idl_txn_add_comment(txn, "ovs-vsctl (invoked by %s): %s",
    2530                 :            :                                   ppid_info, args);
    2531                 :       4526 :         free(ppid_info);
    2532                 :            :     } else {
    2533                 :          0 :         ovsdb_idl_txn_add_comment(txn, "ovs-vsctl: %s", args);
    2534                 :            :     }
    2535                 :            : 
    2536                 :       4526 :     ovs = ovsrec_open_vswitch_first(idl);
    2537         [ +  + ]:       4526 :     if (!ovs) {
    2538                 :            :         /* XXX add verification that table is empty */
    2539                 :        633 :         ovs = ovsrec_open_vswitch_insert(txn);
    2540                 :            :     }
    2541                 :            : 
    2542         [ +  + ]:       4526 :     if (wait_for_reload) {
    2543                 :       3130 :         ovsdb_idl_txn_increment(txn, &ovs->header_,
    2544                 :            :                                 &ovsrec_open_vswitch_col_next_cfg, false);
    2545                 :            :     }
    2546                 :            : 
    2547                 :       4526 :     post_db_reload_check_init();
    2548                 :       4526 :     symtab = ovsdb_symbol_table_create();
    2549         [ +  + ]:      14184 :     for (c = commands; c < &commands[n_commands]; c++) {
    2550                 :       9658 :         ds_init(&c->output);
    2551                 :       9658 :         c->table = NULL;
    2552                 :            :     }
    2553                 :       4526 :     vsctl_context_init(&vsctl_ctx, NULL, idl, txn, ovs, symtab);
    2554         [ +  + ]:      14050 :     for (c = commands; c < &commands[n_commands]; c++) {
    2555                 :       9651 :         vsctl_context_init_command(&vsctl_ctx, c);
    2556         [ +  - ]:       9651 :         if (c->syntax->run) {
    2557                 :       9651 :             (c->syntax->run)(&vsctl_ctx.base);
    2558                 :            :         }
    2559                 :       9531 :         vsctl_context_done_command(&vsctl_ctx, c);
    2560                 :            : 
    2561         [ +  + ]:       9531 :         if (vsctl_ctx.base.try_again) {
    2562                 :          7 :             vsctl_context_done(&vsctl_ctx, NULL);
    2563                 :          7 :             goto try_again;
    2564                 :            :         }
    2565                 :            :     }
    2566                 :       4399 :     vsctl_context_done(&vsctl_ctx, NULL);
    2567                 :            : 
    2568 [ +  + ][ -  + ]:       4509 :     SHASH_FOR_EACH (node, &symtab->sh) {
    2569                 :        110 :         struct ovsdb_symbol *symbol = node->data;
    2570         [ -  + ]:        110 :         if (!symbol->created) {
    2571                 :          0 :             ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
    2572                 :            :                         "with \"-- --id=%s create ...\")",
    2573                 :            :                         node->name, node->name);
    2574                 :            :         }
    2575         [ +  + ]:        110 :         if (!symbol->strong_ref) {
    2576         [ +  + ]:          2 :             if (!symbol->weak_ref) {
    2577         [ +  - ]:          1 :                 VLOG_WARN("row id \"%s\" was created but no reference to it "
    2578                 :            :                           "was inserted, so it will not actually appear in "
    2579                 :            :                           "the database", node->name);
    2580                 :            :             } else {
    2581         [ +  - ]:          1 :                 VLOG_WARN("row id \"%s\" was created but only a weak "
    2582                 :            :                           "reference to it was inserted, so it will not "
    2583                 :            :                           "actually appear in the database", node->name);
    2584                 :            :             }
    2585                 :            :         }
    2586                 :            :     }
    2587                 :            : 
    2588                 :       4399 :     status = ovsdb_idl_txn_commit_block(txn);
    2589 [ +  + ][ +  + ]:       4399 :     if (wait_for_reload && status == TXN_SUCCESS) {
    2590                 :       2150 :         next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
    2591                 :            :     }
    2592 [ +  + ][ +  - ]:       4399 :     if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
    2593         [ +  + ]:      13923 :         for (c = commands; c < &commands[n_commands]; c++) {
    2594         [ +  + ]:       9524 :             if (c->syntax->postprocess) {
    2595                 :         80 :                 vsctl_context_init(&vsctl_ctx, c, idl, txn, ovs, symtab);
    2596                 :         80 :                 (c->syntax->postprocess)(&vsctl_ctx.base);
    2597                 :         80 :                 vsctl_context_done(&vsctl_ctx, c);
    2598                 :            :             }
    2599                 :            :         }
    2600                 :            :     }
    2601                 :       4399 :     error = xstrdup(ovsdb_idl_txn_get_error(txn));
    2602                 :            : 
    2603   [ -  -  +  -  :       4399 :     switch (status) {
                -  -  - ]
    2604                 :            :     case TXN_UNCOMMITTED:
    2605                 :            :     case TXN_INCOMPLETE:
    2606                 :          0 :         OVS_NOT_REACHED();
    2607                 :            : 
    2608                 :            :     case TXN_ABORTED:
    2609                 :            :         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
    2610                 :          0 :         ctl_fatal("transaction aborted");
    2611                 :            : 
    2612                 :            :     case TXN_UNCHANGED:
    2613                 :            :     case TXN_SUCCESS:
    2614                 :       4399 :         break;
    2615                 :            : 
    2616                 :            :     case TXN_TRY_AGAIN:
    2617                 :          0 :         goto try_again;
    2618                 :            : 
    2619                 :            :     case TXN_ERROR:
    2620                 :          0 :         ctl_fatal("transaction error: %s", error);
    2621                 :            : 
    2622                 :            :     case TXN_NOT_LOCKED:
    2623                 :            :         /* Should not happen--we never call ovsdb_idl_set_lock(). */
    2624                 :          0 :         ctl_fatal("database not locked");
    2625                 :            : 
    2626                 :            :     default:
    2627                 :          0 :         OVS_NOT_REACHED();
    2628                 :            :     }
    2629                 :       4399 :     free(error);
    2630                 :            : 
    2631                 :       4399 :     ovsdb_symbol_table_destroy(symtab);
    2632                 :            : 
    2633         [ +  + ]:      13923 :     for (c = commands; c < &commands[n_commands]; c++) {
    2634                 :       9524 :         struct ds *ds = &c->output;
    2635                 :            : 
    2636         [ +  + ]:       9524 :         if (c->table) {
    2637                 :        254 :             table_print(c->table, &table_style);
    2638         [ +  + ]:       9270 :         } else if (oneline) {
    2639                 :            :             size_t j;
    2640                 :            : 
    2641                 :        235 :             ds_chomp(ds, '\n');
    2642         [ +  + ]:       1342 :             for (j = 0; j < ds->length; j++) {
    2643                 :       1107 :                 int ch = ds->string[j];
    2644      [ +  -  + ]:       1107 :                 switch (ch) {
    2645                 :            :                 case '\n':
    2646                 :         15 :                     fputs("\\n", stdout);
    2647                 :         15 :                     break;
    2648                 :            : 
    2649                 :            :                 case '\\':
    2650                 :          0 :                     fputs("\\\\", stdout);
    2651                 :          0 :                     break;
    2652                 :            : 
    2653                 :            :                 default:
    2654                 :       1092 :                     putchar(ch);
    2655                 :            :                 }
    2656                 :            :             }
    2657                 :        235 :             putchar('\n');
    2658                 :            :         } else {
    2659                 :       9035 :             fputs(ds_cstr(ds), stdout);
    2660                 :            :         }
    2661                 :       9524 :         ds_destroy(&c->output);
    2662                 :       9524 :         table_destroy(c->table);
    2663                 :       9524 :         free(c->table);
    2664                 :            : 
    2665                 :       9524 :         shash_destroy_free_data(&c->options);
    2666                 :            :     }
    2667                 :       4399 :     free(commands);
    2668                 :            : 
    2669 [ +  + ][ +  + ]:       4399 :     if (wait_for_reload && status != TXN_UNCHANGED) {
    2670                 :            :         /* Even, if --retry flag was not specified, ovs-vsctl still
    2671                 :            :          * has to retry to establish OVSDB connection, if wait_for_reload
    2672                 :            :          * was set.  Otherwise, ovs-vsctl would end up waiting forever
    2673                 :            :          * until cur_cfg would be updated. */
    2674                 :       2150 :         ovsdb_idl_enable_reconnect(idl);
    2675                 :            :         for (;;) {
    2676                 :       3439 :             ovsdb_idl_run(idl);
    2677         [ +  + ]:       4728 :             OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
    2678         [ +  + ]:       3439 :                 if (ovs->cur_cfg >= next_cfg) {
    2679                 :       2150 :                     post_db_reload_do_checks(&vsctl_ctx);
    2680                 :       2150 :                     goto done;
    2681                 :            :                 }
    2682                 :            :             }
    2683                 :       1289 :             ovsdb_idl_wait(idl);
    2684                 :       1289 :             poll_block();
    2685                 :       1289 :         }
    2686                 :            :     done: ;
    2687                 :            :     }
    2688                 :       4399 :     ovsdb_idl_txn_destroy(txn);
    2689                 :       4399 :     ovsdb_idl_destroy(idl);
    2690                 :            : 
    2691                 :       4399 :     exit(EXIT_SUCCESS);
    2692                 :            : 
    2693                 :            : try_again:
    2694                 :            :     /* Our transaction needs to be rerun, or a prerequisite was not met.  Free
    2695                 :            :      * resources and return so that the caller can try again. */
    2696         [ +  - ]:          7 :     if (txn) {
    2697                 :          7 :         ovsdb_idl_txn_abort(txn);
    2698                 :          7 :         ovsdb_idl_txn_destroy(txn);
    2699                 :          7 :         the_idl_txn = NULL;
    2700                 :            :     }
    2701                 :          7 :     ovsdb_symbol_table_destroy(symtab);
    2702         [ +  + ]:         21 :     for (c = commands; c < &commands[n_commands]; c++) {
    2703                 :         14 :         ds_destroy(&c->output);
    2704                 :         14 :         table_destroy(c->table);
    2705                 :         14 :         free(c->table);
    2706                 :            :     }
    2707                 :          7 :     free(error);
    2708                 :          7 : }
    2709                 :            : 
    2710                 :            : /* Frees the current transaction and the underlying IDL and then calls
    2711                 :            :  * exit(status).
    2712                 :            :  *
    2713                 :            :  * Freeing the transaction and the IDL is not strictly necessary, but it makes
    2714                 :            :  * for a clean memory leak report from valgrind in the normal case.  That makes
    2715                 :            :  * it easier to notice real memory leaks. */
    2716                 :            : static void
    2717                 :        134 : vsctl_exit(int status)
    2718                 :            : {
    2719         [ +  + ]:        134 :     if (the_idl_txn) {
    2720                 :        120 :         ovsdb_idl_txn_abort(the_idl_txn);
    2721                 :        120 :         ovsdb_idl_txn_destroy(the_idl_txn);
    2722                 :            :     }
    2723                 :        134 :     ovsdb_idl_destroy(the_idl);
    2724                 :        134 :     exit(status);
    2725                 :            : }
    2726                 :            : 
    2727                 :            : /*
    2728                 :            :  * Developers who add new commands to the 'struct ctl_command_syntax' must
    2729                 :            :  * define the 'arguments' member of the struct.  The following keywords are
    2730                 :            :  * available for composing the argument format:
    2731                 :            :  *
    2732                 :            :  *    TABLE     RECORD       BRIDGE       PARENT         PORT
    2733                 :            :  *    KEY       VALUE        ARG          KEY=VALUE      ?KEY=VALUE
    2734                 :            :  *    IFACE     SYSIFACE     COLUMN       COLUMN?:KEY    COLUMN?:KEY=VALUE
    2735                 :            :  *    MODE      CA-CERT      CERTIFICATE  PRIVATE-KEY
    2736                 :            :  *    TARGET    NEW-* (e.g. NEW-PORT)
    2737                 :            :  *
    2738                 :            :  * For argument types not listed above, just uses 'ARG' as place holder.
    2739                 :            :  *
    2740                 :            :  * Encloses the keyword with '[]' if it is optional.  Appends '...' to
    2741                 :            :  * keyword or enclosed keyword to indicate that the argument can be specified
    2742                 :            :  * multiple times.
    2743                 :            :  *
    2744                 :            :  * */
    2745                 :            : static const struct ctl_command_syntax vsctl_commands[] = {
    2746                 :            :     /* Open vSwitch commands. */
    2747                 :            :     {"init", 0, 0, "", NULL, cmd_init, NULL, "", RW},
    2748                 :            : 
    2749                 :            :     /* Bridge commands. */
    2750                 :            :     {"add-br", 1, 3, "NEW-BRIDGE [PARENT] [NEW-VLAN]", pre_get_info,
    2751                 :            :      cmd_add_br, NULL, "--may-exist", RW},
    2752                 :            :     {"del-br", 1, 1, "BRIDGE", pre_get_info, cmd_del_br,
    2753                 :            :      NULL, "--if-exists", RW},
    2754                 :            :     {"list-br", 0, 0, "", pre_get_info, cmd_list_br, NULL, "--real,--fake",
    2755                 :            :      RO},
    2756                 :            :     {"br-exists", 1, 1, "BRIDGE", pre_get_info, cmd_br_exists, NULL, "", RO},
    2757                 :            :     {"br-to-vlan", 1, 1, "BRIDGE", pre_get_info, cmd_br_to_vlan, NULL, "",
    2758                 :            :      RO},
    2759                 :            :     {"br-to-parent", 1, 1, "BRIDGE", pre_get_info, cmd_br_to_parent, NULL,
    2760                 :            :      "", RO},
    2761                 :            :     {"br-set-external-id", 2, 3, "BRIDGE KEY [VALUE]",
    2762                 :            :      pre_cmd_br_set_external_id, cmd_br_set_external_id, NULL, "", RW},
    2763                 :            :     {"br-get-external-id", 1, 2, "BRIDGE [KEY]", pre_cmd_br_get_external_id,
    2764                 :            :      cmd_br_get_external_id, NULL, "", RO},
    2765                 :            : 
    2766                 :            :     /* Port commands. */
    2767                 :            :     {"list-ports", 1, 1, "BRIDGE", pre_get_info, cmd_list_ports, NULL, "",
    2768                 :            :      RO},
    2769                 :            :     {"add-port", 2, INT_MAX, "BRIDGE NEW-PORT [COLUMN[:KEY]=VALUE]...",
    2770                 :            :      pre_get_info, cmd_add_port, NULL, "--may-exist", RW},
    2771                 :            :     {"add-bond", 4, INT_MAX,
    2772                 :            :      "BRIDGE NEW-BOND-PORT SYSIFACE... [COLUMN[:KEY]=VALUE]...", pre_get_info,
    2773                 :            :      cmd_add_bond, NULL, "--may-exist,--fake-iface", RW},
    2774                 :            :     {"del-port", 1, 2, "[BRIDGE] PORT|IFACE", pre_get_info, cmd_del_port, NULL,
    2775                 :            :      "--if-exists,--with-iface", RW},
    2776                 :            :     {"port-to-br", 1, 1, "PORT", pre_get_info, cmd_port_to_br, NULL, "", RO},
    2777                 :            : 
    2778                 :            :     /* Interface commands. */
    2779                 :            :     {"list-ifaces", 1, 1, "BRIDGE", pre_get_info, cmd_list_ifaces, NULL, "",
    2780                 :            :      RO},
    2781                 :            :     {"iface-to-br", 1, 1, "IFACE", pre_get_info, cmd_iface_to_br, NULL, "",
    2782                 :            :      RO},
    2783                 :            : 
    2784                 :            :     /* Controller commands. */
    2785                 :            :     {"get-controller", 1, 1, "BRIDGE", pre_controller, cmd_get_controller,
    2786                 :            :      NULL, "", RO},
    2787                 :            :     {"del-controller", 1, 1, "BRIDGE", pre_controller, cmd_del_controller,
    2788                 :            :      NULL, "", RW},
    2789                 :            :     {"set-controller", 1, INT_MAX, "BRIDGE TARGET...", pre_controller,
    2790                 :            :      cmd_set_controller, NULL, "", RW},
    2791                 :            :     {"get-fail-mode", 1, 1, "BRIDGE", pre_get_info, cmd_get_fail_mode, NULL,
    2792                 :            :      "", RO},
    2793                 :            :     {"del-fail-mode", 1, 1, "BRIDGE", pre_get_info, cmd_del_fail_mode, NULL,
    2794                 :            :      "", RW},
    2795                 :            :     {"set-fail-mode", 2, 2, "BRIDGE MODE", pre_get_info, cmd_set_fail_mode,
    2796                 :            :      NULL, "", RW},
    2797                 :            : 
    2798                 :            :     /* Manager commands. */
    2799                 :            :     {"get-manager", 0, 0, "", pre_manager, cmd_get_manager, NULL, "", RO},
    2800                 :            :     {"del-manager", 0, 0, "", pre_manager, cmd_del_manager, NULL, "", RW},
    2801                 :            :     {"set-manager", 1, INT_MAX, "TARGET...", pre_manager, cmd_set_manager,
    2802                 :            :      NULL, "", RW},
    2803                 :            : 
    2804                 :            :     /* SSL commands. */
    2805                 :            :     {"get-ssl", 0, 0, "", pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
    2806                 :            :     {"del-ssl", 0, 0, "", pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},
    2807                 :            :     {"set-ssl", 3, 3, "PRIVATE-KEY CERTIFICATE CA-CERT", pre_cmd_set_ssl,
    2808                 :            :      cmd_set_ssl, NULL, "--bootstrap", RW},
    2809                 :            : 
    2810                 :            :     /* Auto Attach commands. */
    2811                 :            :     {"add-aa-mapping", 3, 3, "BRIDGE ARG ARG", pre_aa_mapping, cmd_add_aa_mapping,
    2812                 :            :      NULL, "", RW},
    2813                 :            :     {"del-aa-mapping", 3, 3, "BRIDGE ARG ARG", pre_aa_mapping, cmd_del_aa_mapping,
    2814                 :            :      NULL, "", RW},
    2815                 :            :     {"get-aa-mapping", 1, 1, "BRIDGE", pre_aa_mapping, cmd_get_aa_mapping,
    2816                 :            :      NULL, "", RO},
    2817                 :            : 
    2818                 :            :     /* Switch commands. */
    2819                 :            :     {"emer-reset", 0, 0, "", pre_cmd_emer_reset, cmd_emer_reset, NULL, "", RW},
    2820                 :            : 
    2821                 :            :     {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
    2822                 :            : };
    2823                 :            : 
    2824                 :            : /* Registers vsctl and common db commands. */
    2825                 :            : static void
    2826                 :       4650 : vsctl_cmd_init(void)
    2827                 :            : {
    2828                 :       4650 :     ctl_init(tables, cmd_show_tables, vsctl_exit);
    2829                 :       4650 :     ctl_register_commands(vsctl_commands);
    2830                 :       4650 : }

Generated by: LCOV version 1.12