ovn-nbctl: Update basic router commands.
[cascardo/ovs.git] / ovn / utilities / ovn-nbctl.c
1 /*
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at:
5  *
6  *     http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14
15 #include <config.h>
16
17 #include <getopt.h>
18 #include <inttypes.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21
22 #include "command-line.h"
23 #include "db-ctl-base.h"
24 #include "dirs.h"
25 #include "fatal-signal.h"
26 #include "json.h"
27 #include "ovn/lib/ovn-nb-idl.h"
28 #include "packets.h"
29 #include "poll-loop.h"
30 #include "process.h"
31 #include "smap.h"
32 #include "stream.h"
33 #include "stream-ssl.h"
34 #include "svec.h"
35 #include "table.h"
36 #include "timeval.h"
37 #include "util.h"
38 #include "openvswitch/vlog.h"
39
40 VLOG_DEFINE_THIS_MODULE(nbctl);
41
42 /* --db: The database server to contact. */
43 static const char *db;
44
45 /* --oneline: Write each command's output as a single line? */
46 static bool oneline;
47
48 /* --dry-run: Do not commit any changes. */
49 static bool dry_run;
50
51 /* --timeout: Time to wait for a connection to 'db'. */
52 static int timeout;
53
54 /* Format for table output. */
55 static struct table_style table_style = TABLE_STYLE_DEFAULT;
56
57 /* The IDL we're using and the current transaction, if any.
58  * This is for use by nbctl_exit() only, to allow it to clean up.
59  * Other code should use its context arguments. */
60 static struct ovsdb_idl *the_idl;
61 static struct ovsdb_idl_txn *the_idl_txn;
62 OVS_NO_RETURN static void nbctl_exit(int status);
63
64 static void nbctl_cmd_init(void);
65 OVS_NO_RETURN static void usage(void);
66 static void parse_options(int argc, char *argv[], struct shash *local_options);
67 static const char *nbctl_default_db(void);
68 static void run_prerequisites(struct ctl_command[], size_t n_commands,
69                               struct ovsdb_idl *);
70 static bool do_nbctl(const char *args, struct ctl_command *, size_t n,
71                      struct ovsdb_idl *);
72
73 int
74 main(int argc, char *argv[])
75 {
76     struct ovsdb_idl *idl;
77     struct ctl_command *commands;
78     struct shash local_options;
79     unsigned int seqno;
80     size_t n_commands;
81     char *args;
82
83     set_program_name(argv[0]);
84     fatal_ignore_sigpipe();
85     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
86     vlog_set_levels_from_string_assert("reconnect:warn");
87     nbrec_init();
88
89     nbctl_cmd_init();
90
91     /* Log our arguments.  This is often valuable for debugging systems. */
92     args = process_escape_args(argv);
93     VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG,
94          "Called as %s", args);
95
96     /* Parse command line. */
97     shash_init(&local_options);
98     parse_options(argc, argv, &local_options);
99     commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
100                                   &n_commands);
101
102     if (timeout) {
103         time_alarm(timeout);
104     }
105
106     /* Initialize IDL. */
107     idl = the_idl = ovsdb_idl_create(db, &nbrec_idl_class, true, false);
108     run_prerequisites(commands, n_commands, idl);
109
110     /* Execute the commands.
111      *
112      * 'seqno' is the database sequence number for which we last tried to
113      * execute our transaction.  There's no point in trying to commit more than
114      * once for any given sequence number, because if the transaction fails
115      * it's because the database changed and we need to obtain an up-to-date
116      * view of the database before we try the transaction again. */
117     seqno = ovsdb_idl_get_seqno(idl);
118     for (;;) {
119         ovsdb_idl_run(idl);
120         if (!ovsdb_idl_is_alive(idl)) {
121             int retval = ovsdb_idl_get_last_error(idl);
122             ctl_fatal("%s: database connection failed (%s)",
123                         db, ovs_retval_to_string(retval));
124         }
125
126         if (seqno != ovsdb_idl_get_seqno(idl)) {
127             seqno = ovsdb_idl_get_seqno(idl);
128             if (do_nbctl(args, commands, n_commands, idl)) {
129                 free(args);
130                 exit(EXIT_SUCCESS);
131             }
132         }
133
134         if (seqno == ovsdb_idl_get_seqno(idl)) {
135             ovsdb_idl_wait(idl);
136             poll_block();
137         }
138     }
139 }
140
141 static const char *
142 nbctl_default_db(void)
143 {
144     static char *def;
145     if (!def) {
146         def = getenv("OVN_NB_DB");
147         if (!def) {
148             def = xasprintf("unix:%s/ovnnb_db.sock", ovs_rundir());
149         }
150     }
151     return def;
152 }
153
154 static void
155 parse_options(int argc, char *argv[], struct shash *local_options)
156 {
157     enum {
158         OPT_DB = UCHAR_MAX + 1,
159         OPT_NO_SYSLOG,
160         OPT_DRY_RUN,
161         OPT_ONELINE,
162         OPT_LOCAL,
163         OPT_COMMANDS,
164         OPT_OPTIONS,
165         VLOG_OPTION_ENUMS,
166         TABLE_OPTION_ENUMS
167     };
168     static const struct option global_long_options[] = {
169         {"db", required_argument, NULL, OPT_DB},
170         {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
171         {"dry-run", no_argument, NULL, OPT_DRY_RUN},
172         {"oneline", no_argument, NULL, OPT_ONELINE},
173         {"timeout", required_argument, NULL, 't'},
174         {"help", no_argument, NULL, 'h'},
175         {"commands", no_argument, NULL, OPT_COMMANDS},
176         {"options", no_argument, NULL, OPT_OPTIONS},
177         {"version", no_argument, NULL, 'V'},
178         VLOG_LONG_OPTIONS,
179         STREAM_SSL_LONG_OPTIONS,
180         TABLE_LONG_OPTIONS,
181         {NULL, 0, NULL, 0},
182     };
183     const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
184     char *tmp, *short_options;
185
186     struct option *options;
187     size_t allocated_options;
188     size_t n_options;
189     size_t i;
190
191     tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
192     short_options = xasprintf("+%s", tmp);
193     free(tmp);
194
195     /* We want to parse both global and command-specific options here, but
196      * getopt_long() isn't too convenient for the job.  We copy our global
197      * options into a dynamic array, then append all of the command-specific
198      * options. */
199     options = xmemdup(global_long_options, sizeof global_long_options);
200     allocated_options = ARRAY_SIZE(global_long_options);
201     n_options = n_global_long_options;
202     ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
203     table_style.format = TF_LIST;
204
205     for (;;) {
206         int idx;
207         int c;
208
209         c = getopt_long(argc, argv, short_options, options, &idx);
210         if (c == -1) {
211             break;
212         }
213
214         switch (c) {
215         case OPT_DB:
216             db = optarg;
217             break;
218
219         case OPT_ONELINE:
220             oneline = true;
221             break;
222
223         case OPT_NO_SYSLOG:
224             vlog_set_levels(&this_module, VLF_SYSLOG, VLL_WARN);
225             break;
226
227         case OPT_DRY_RUN:
228             dry_run = true;
229             break;
230
231         case OPT_LOCAL:
232             if (shash_find(local_options, options[idx].name)) {
233                 ctl_fatal("'%s' option specified multiple times",
234                             options[idx].name);
235             }
236             shash_add_nocopy(local_options,
237                              xasprintf("--%s", options[idx].name),
238                              optarg ? xstrdup(optarg) : NULL);
239             break;
240
241         case 'h':
242             usage();
243             exit(EXIT_SUCCESS);
244
245         case OPT_COMMANDS:
246             ctl_print_commands();
247
248         case OPT_OPTIONS:
249             ctl_print_options(global_long_options);
250
251         case 'V':
252             ovs_print_version(0, 0);
253             printf("DB Schema %s\n", nbrec_get_db_version());
254             exit(EXIT_SUCCESS);
255
256         case 't':
257             timeout = strtoul(optarg, NULL, 10);
258             if (timeout < 0) {
259                 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
260             }
261             break;
262
263         VLOG_OPTION_HANDLERS
264         TABLE_OPTION_HANDLERS(&table_style)
265         STREAM_SSL_OPTION_HANDLERS
266
267         case '?':
268             exit(EXIT_FAILURE);
269
270         default:
271             abort();
272         }
273     }
274     free(short_options);
275
276     if (!db) {
277         db = nbctl_default_db();
278     }
279
280     for (i = n_global_long_options; options[i].name; i++) {
281         free(CONST_CAST(char *, options[i].name));
282     }
283     free(options);
284 }
285
286 static void
287 usage(void)
288 {
289     printf("\
290 %s: OVN northbound DB management utility\n\
291 usage: %s [OPTIONS] COMMAND [ARG...]\n\
292 \n\
293 General commands:\n\
294   show                      print overview of database contents\n\
295   show LSWITCH              print overview of database contents for LSWITCH\n\
296   show ROUTER               print overview of database contents for ROUTER\n\
297 \n\
298 Logical switch commands:\n\
299   lswitch-add [LSWITCH]     create a logical switch named LSWITCH\n\
300   lswitch-del LSWITCH       delete LSWITCH and all its ports\n\
301   lswitch-list              print the names of all logical switches\n\
302 \n\
303 ACL commands:\n\
304   acl-add LSWITCH DIRECTION PRIORITY MATCH ACTION [log]\n\
305                             add an ACL to LSWITCH\n\
306   acl-del LSWITCH [DIRECTION [PRIORITY MATCH]]\n\
307                             remove ACLs from LSWITCH\n\
308   acl-list LSWITCH          print ACLs for LSWITCH\n\
309 \n\
310 Logical router port commands:\n\
311   lrport-add ROUTER LRPORT  add logical router port LRPORT to ROUTER\n\
312   lrport-del LRPORT         delete LRPORT from its attached router\n\
313   lrport-list ROUTER        print the names of all logical ports on ROUTER\n\
314   lrport-set-mac-address LRPORT [ADDRESS]\n\
315                             set MAC address for LRPORT.\n\
316   lrport-get-mac-address LRPORT      get MAC addresses on LRPORT\n\
317   lrport-set-enabled LRPORT STATE\n\
318                             set administrative state LRPORT\n\
319                             ('enabled' or 'disabled')\n\
320   lrport-get-enabled LRPORT   get administrative state LRPORT\n\
321                             ('enabled' or 'disabled')\n\
322 \n\
323 Logical port commands:\n\
324   lport-add LSWITCH LPORT   add logical port LPORT on LSWITCH\n\
325   lport-add LSWITCH LPORT PARENT TAG\n\
326                             add logical port LPORT on LSWITCH with PARENT\n\
327                             on TAG\n\
328   lport-del LPORT           delete LPORT from its attached switch\n\
329   lport-list LSWITCH        print the names of all logical ports on LSWITCH\n\
330   lport-get-parent LPORT    get the parent of LPORT if set\n\
331   lport-get-tag LPORT       get the LPORT's tag if set\n\
332   lport-set-addresses LPORT [ADDRESS]...\n\
333                             set MAC or MAC+IP addresses for LPORT.\n\
334   lport-get-addresses LPORT      get a list of MAC addresses on LPORT\n\
335   lport-set-port-security LPORT [ADDRS]...\n\
336                             set port security addresses for LPORT.\n\
337   lport-get-port-security LPORT    get LPORT's port security addresses\n\
338   lport-get-up LPORT        get state of LPORT ('up' or 'down')\n\
339   lport-set-enabled LPORT STATE\n\
340                             set administrative state LPORT\n\
341                             ('enabled' or 'disabled')\n\
342   lport-get-enabled LPORT   get administrative state LPORT\n\
343                             ('enabled' or 'disabled')\n\
344   lport-set-type LPORT TYPE Set the type for LPORT\n\
345   lport-get-type LPORT      Get the type for LPORT\n\
346   lport-set-options LPORT KEY=VALUE [KEY=VALUE]...\n\
347                             Set options related to the type of LPORT\n\
348   lport-get-options LPORT   Get the type specific options for LPORT\n\
349 \n\
350 Logical router commands:\n\
351   lr-add [ROUTER]           create a logical router named ROUTER\n\
352   lr-del ROUTER             delete ROUTER and all its ports\n\
353   lr-list                   print the names of all logical routers\n\
354 \n\
355 %s\
356 \n\
357 Options:\n\
358   --db=DATABASE               connect to DATABASE\n\
359                               (default: %s)\n\
360   -t, --timeout=SECS          wait at most SECS seconds\n\
361   --dry-run                   do not commit changes to database\n\
362   --oneline                   print exactly one line of output per command\n",
363            program_name, program_name, ctl_get_db_cmd_usage(), nbctl_default_db());
364     vlog_usage();
365     printf("\
366   --no-syslog             equivalent to --verbose=nbctl:syslog:warn\n");
367     printf("\n\
368 Other options:\n\
369   -h, --help                  display this help message\n\
370   -V, --version               display version information\n");
371     exit(EXIT_SUCCESS);
372 }
373 \f
374
375 /* Find a logical router given its id. */
376 static const struct nbrec_logical_router *
377 lr_by_name_or_uuid(struct ctl_context *ctx, const char *id,
378                         bool must_exist)
379 {
380     const struct nbrec_logical_router *lr = NULL;
381     bool is_uuid = false;
382     struct uuid lr_uuid;
383
384     if (uuid_from_string(&lr_uuid, id)) {
385         is_uuid = true;
386         lr = nbrec_logical_router_get_for_uuid(ctx->idl, &lr_uuid);
387     }
388
389     if (!lr) {
390         const struct nbrec_logical_router *iter;
391
392         NBREC_LOGICAL_ROUTER_FOR_EACH(iter, ctx->idl) {
393             if (strcmp(iter->name, id)) {
394                 continue;
395             }
396             if (lr) {
397                 ctl_fatal("Multiple logical routers named '%s'.  "
398                           "Use a UUID.", id);
399             }
400             lr = iter;
401         }
402     }
403
404     if (!lr && must_exist) {
405         ctl_fatal("%s: router %s not found", id, is_uuid ? "UUID" : "name");
406     }
407
408     return lr;
409 }
410
411 static const struct nbrec_logical_switch *
412 lswitch_by_name_or_uuid(struct ctl_context *ctx, const char *id,
413                         bool must_exist)
414 {
415     const struct nbrec_logical_switch *lswitch = NULL;
416
417     struct uuid lswitch_uuid;
418     bool is_uuid = uuid_from_string(&lswitch_uuid, id);
419     if (is_uuid) {
420         lswitch = nbrec_logical_switch_get_for_uuid(ctx->idl, &lswitch_uuid);
421     }
422
423     if (!lswitch) {
424         const struct nbrec_logical_switch *iter;
425
426         NBREC_LOGICAL_SWITCH_FOR_EACH(iter, ctx->idl) {
427             if (strcmp(iter->name, id)) {
428                 continue;
429             }
430             if (lswitch) {
431                 ctl_fatal("Multiple logical switches named '%s'.  "
432                           "Use a UUID.", id);
433             }
434             lswitch = iter;
435         }
436     }
437
438     if (!lswitch && must_exist) {
439         ctl_fatal("%s: lswitch %s not found", id, is_uuid ? "UUID" : "name");
440     }
441
442     return lswitch;
443 }
444
445 /* Given pointer to logical router, this routine prints the router
446  * information.  */
447 static void
448 print_lr(const struct nbrec_logical_router *lr, struct ds *s)
449 {
450     ds_put_format(s, "    router "UUID_FMT" (%s)\n",
451                   UUID_ARGS(&lr->header_.uuid), lr->name);
452
453     for (size_t i = 0; i < lr->n_ports; i++) {
454         const struct nbrec_logical_router_port *lrport = lr->ports[i];
455         ds_put_format(s, "        lrport %s\n", lrport->name);
456         if (lrport->mac) {
457             ds_put_cstr(s, "            mac: ");
458             ds_put_format(s, "\"%s\"", lrport->mac);
459         }
460         ds_put_format(s, "\n");
461     }
462 }
463
464 static void
465 print_lswitch(const struct nbrec_logical_switch *lswitch, struct ds *s)
466 {
467     ds_put_format(s, "    lswitch "UUID_FMT" (%s)\n",
468                   UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
469
470     for (size_t i = 0; i < lswitch->n_ports; i++) {
471         const struct nbrec_logical_port *lport = lswitch->ports[i];
472
473         ds_put_format(s, "        lport %s\n", lport->name);
474         if (lport->parent_name) {
475             ds_put_format(s, "            parent: %s\n", lport->parent_name);
476         }
477         if (lport->n_tag) {
478             ds_put_format(s, "            tag: %"PRIu64"\n", lport->tag[0]);
479         }
480         if (lport->n_addresses) {
481             ds_put_cstr(s, "            addresses: [");
482             for (size_t j = 0; j < lport->n_addresses; j++) {
483                 ds_put_format(s, "%s\"%s\"",
484                         j == 0 ? "" : ", ",
485                         lport->addresses[j]);
486             }
487             ds_put_cstr(s, "]\n");
488         }
489     }
490 }
491
492 static void
493 nbctl_show(struct ctl_context *ctx)
494 {
495     const struct nbrec_logical_switch *lswitch;
496
497     if (ctx->argc == 2) {
498         lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1], false);
499         if (lswitch) {
500             print_lswitch(lswitch, &ctx->output);
501         }
502     } else {
503         NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, ctx->idl) {
504             print_lswitch(lswitch, &ctx->output);
505         }
506     }
507     const struct nbrec_logical_router *lr;
508
509     if (ctx->argc == 2) {
510         lr = lr_by_name_or_uuid(ctx, ctx->argv[1], false);
511         if (lr) {
512             print_lr(lr, &ctx->output);
513         }
514     } else {
515         NBREC_LOGICAL_ROUTER_FOR_EACH(lr, ctx->idl) {
516             print_lr(lr, &ctx->output);
517         }
518     }
519 }
520
521 static void
522 nbctl_lswitch_add(struct ctl_context *ctx)
523 {
524     const char *lswitch_name = ctx->argc == 2 ? ctx->argv[1] : NULL;
525
526     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
527     bool add_duplicate = shash_find(&ctx->options, "--add-duplicate") != NULL;
528     if (may_exist && add_duplicate) {
529         ctl_fatal("--may-exist and --add-duplicate may not be used together");
530     }
531
532     if (lswitch_name) {
533         if (!add_duplicate) {
534             const struct nbrec_logical_switch *lswitch;
535             NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, ctx->idl) {
536                 if (!strcmp(lswitch->name, lswitch_name)) {
537                     if (may_exist) {
538                         return;
539                     }
540                     ctl_fatal("%s: an lswitch with this name already exists",
541                               lswitch_name);
542                 }
543             }
544         }
545     } else if (may_exist) {
546         ctl_fatal("--may-exist requires specifying a name");
547     } else if (add_duplicate) {
548         ctl_fatal("--add-duplicate requires specifying a name");
549     }
550
551     struct nbrec_logical_switch *lswitch;
552     lswitch = nbrec_logical_switch_insert(ctx->txn);
553     if (lswitch_name) {
554         nbrec_logical_switch_set_name(lswitch, lswitch_name);
555     }
556 }
557
558 static void
559 nbctl_lswitch_del(struct ctl_context *ctx)
560 {
561     bool must_exist = !shash_find(&ctx->options, "--if-exists");
562     const char *id = ctx->argv[1];
563     const struct nbrec_logical_switch *lswitch;
564
565     lswitch = lswitch_by_name_or_uuid(ctx, id, must_exist);
566     if (!lswitch) {
567         return;
568     }
569
570     nbrec_logical_switch_delete(lswitch);
571 }
572
573 static void
574 nbctl_lswitch_list(struct ctl_context *ctx)
575 {
576     const struct nbrec_logical_switch *lswitch;
577     struct smap lswitches;
578
579     smap_init(&lswitches);
580     NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, ctx->idl) {
581         smap_add_format(&lswitches, lswitch->name, UUID_FMT " (%s)",
582                         UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
583     }
584     const struct smap_node **nodes = smap_sort(&lswitches);
585     for (size_t i = 0; i < smap_count(&lswitches); i++) {
586         const struct smap_node *node = nodes[i];
587         ds_put_format(&ctx->output, "%s\n", node->value);
588     }
589     smap_destroy(&lswitches);
590     free(nodes);
591 }
592 \f
593 /* Find the lrport given its id. */
594 static const struct nbrec_logical_router_port *
595 lrport_by_name_or_uuid(struct ctl_context *ctx, const char *id,
596                        bool must_exist)
597 {
598     const struct nbrec_logical_router_port *lrport = NULL;
599     bool is_uuid = false;
600     struct uuid lrport_uuid;
601
602     if (uuid_from_string(&lrport_uuid, id)) {
603         is_uuid = true;
604         lrport = nbrec_logical_router_port_get_for_uuid(ctx->idl,
605                                                         &lrport_uuid);
606     }
607
608     if (!lrport) {
609         NBREC_LOGICAL_ROUTER_PORT_FOR_EACH(lrport, ctx->idl) {
610             if (!strcmp(lrport->name, id)) {
611                 break;
612             }
613         }
614     }
615
616     if (!lrport && must_exist) {
617         ctl_fatal("%s: lrport with this %s not found",
618                   id, is_uuid ? "name" : "UUID");
619     }
620
621     return lrport;
622 }
623
624 static const struct nbrec_logical_port *
625 lport_by_name_or_uuid(struct ctl_context *ctx, const char *id,
626                       bool must_exist)
627 {
628     const struct nbrec_logical_port *lport = NULL;
629
630     struct uuid lport_uuid;
631     bool is_uuid = uuid_from_string(&lport_uuid, id);
632     if (is_uuid) {
633         lport = nbrec_logical_port_get_for_uuid(ctx->idl, &lport_uuid);
634     }
635
636     if (!lport) {
637         NBREC_LOGICAL_PORT_FOR_EACH(lport, ctx->idl) {
638             if (!strcmp(lport->name, id)) {
639                 break;
640             }
641         }
642     }
643
644     if (!lport && must_exist) {
645         ctl_fatal("%s: lport %s not found", id, is_uuid ? "UUID" : "name");
646     }
647
648     return lport;
649 }
650
651 /* Returns the lswitch that contains 'lport'. */
652 static const struct nbrec_logical_switch *
653 lport_to_lswitch(const struct ovsdb_idl *idl,
654                  const struct nbrec_logical_port *lport)
655 {
656     const struct nbrec_logical_switch *lswitch;
657     NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, idl) {
658         for (size_t i = 0; i < lswitch->n_ports; i++) {
659             if (lswitch->ports[i] == lport) {
660                 return lswitch;
661             }
662         }
663     }
664
665     /* Can't happen because of the database schema */
666     ctl_fatal("logical port %s is not part of any logical switch",
667               lport->name);
668 }
669
670 /* Returns the logical router that contains 'lport'. */
671 static const struct nbrec_logical_router *
672 lrport_to_lr(const struct ovsdb_idl *idl,
673              const struct nbrec_logical_router_port *lrport)
674 {
675     const struct nbrec_logical_router *lr;
676     NBREC_LOGICAL_ROUTER_FOR_EACH (lr, idl) {
677         for (size_t i = 0; i < lr->n_ports; i++) {
678             if (lr->ports[i] == lrport) {
679                 return lr;
680             }
681         }
682     }
683
684     /* Can't happen because of the database schema */
685     ctl_fatal("logical port %s is not part of any logical router",
686               lrport->name);
687 }
688
689 static const char *
690 lswitch_get_name(const struct nbrec_logical_switch *lswitch,
691                  char uuid_s[UUID_LEN + 1], size_t uuid_s_size)
692 {
693     if (lswitch->name[0]) {
694         return lswitch->name;
695     }
696     snprintf(uuid_s, uuid_s_size, UUID_FMT, UUID_ARGS(&lswitch->header_.uuid));
697     return uuid_s;
698 }
699
700 static const char *
701 lr_get_name(const struct nbrec_logical_router *lr,
702             char uuid_s[UUID_LEN + 1], size_t uuid_s_size)
703 {
704     if (lr->name[0]) {
705         return lr->name;
706     }
707     snprintf(uuid_s, uuid_s_size, UUID_FMT, UUID_ARGS(&lr->header_.uuid));
708     return uuid_s;
709 }
710
711 static void
712 nbctl_lport_add(struct ctl_context *ctx)
713 {
714     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
715
716     const struct nbrec_logical_switch *lswitch;
717     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1], true);
718
719     const char *parent_name;
720     int64_t tag;
721     if (ctx->argc == 3) {
722         parent_name = NULL;
723         tag = -1;
724     } else if (ctx->argc == 5) {
725         /* Validate tag. */
726         parent_name = ctx->argv[3];
727         if (!ovs_scan(ctx->argv[4], "%"SCNd64, &tag)
728             || tag < 0 || tag > 4095) {
729             ctl_fatal("%s: invalid tag", ctx->argv[4]);
730         }
731     } else {
732         ctl_fatal("lport-add with parent must also specify a tag");
733     }
734
735     const char *lport_name = ctx->argv[2];
736     const struct nbrec_logical_port *lport;
737     lport = lport_by_name_or_uuid(ctx, lport_name, false);
738     if (lport) {
739         if (!may_exist) {
740             ctl_fatal("%s: an lport with this name already exists",
741                       lport_name);
742         }
743
744         const struct nbrec_logical_switch *lsw;
745         lsw = lport_to_lswitch(ctx->idl, lport);
746         if (lsw != lswitch) {
747             char uuid_s[UUID_LEN + 1];
748             ctl_fatal("%s: lport already exists but in lswitch %s", lport_name,
749                       lswitch_get_name(lsw, uuid_s, sizeof uuid_s));
750         }
751
752         if (parent_name) {
753             if (!lport->parent_name) {
754                 ctl_fatal("%s: lport already exists but has no parent",
755                           lport_name);
756             } else if (strcmp(parent_name, lport->parent_name)) {
757                 ctl_fatal("%s: lport already exists with different parent %s",
758                           lport_name, lport->parent_name);
759             }
760
761             if (!lport->n_tag) {
762                 ctl_fatal("%s: lport already exists but has no tag",
763                           lport_name);
764             } else if (lport->tag[0] != tag) {
765                 ctl_fatal("%s: lport already exists with different "
766                           "tag %"PRId64, lport_name, lport->tag[0]);
767             }
768         } else {
769             if (lport->parent_name) {
770                 ctl_fatal("%s: lport already exists but has parent %s",
771                           lport_name, lport->parent_name);
772             }
773         }
774
775         return;
776     }
777
778     /* Create the logical port. */
779     lport = nbrec_logical_port_insert(ctx->txn);
780     nbrec_logical_port_set_name(lport, lport_name);
781     if (tag >= 0) {
782         nbrec_logical_port_set_parent_name(lport, parent_name);
783         nbrec_logical_port_set_tag(lport, &tag, 1);
784     }
785
786     /* Insert the logical port into the logical switch. */
787     nbrec_logical_switch_verify_ports(lswitch);
788     struct nbrec_logical_port **new_ports = xmalloc(sizeof *new_ports *
789                                                     (lswitch->n_ports + 1));
790     memcpy(new_ports, lswitch->ports, sizeof *new_ports * lswitch->n_ports);
791     new_ports[lswitch->n_ports] = CONST_CAST(struct nbrec_logical_port *,
792                                              lport);
793     nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports + 1);
794     free(new_ports);
795 }
796
797 /* Removes lrport 'lr->ports[idx]' from logical router. */
798 static void
799 remove_lrport(const struct nbrec_logical_router *lr, size_t idx)
800 {
801     const struct nbrec_logical_router_port *lrport = lr->ports[idx];
802
803     /* First remove 'lrport' from the array of ports.  This is what will
804      * actually cause the logical port to be deleted when the transaction is
805      * sent to the database server (due to garbage collection). */
806     struct nbrec_logical_router_port **new_ports
807         = xmemdup(lr->ports, sizeof *new_ports * lr->n_ports);
808     new_ports[idx] = new_ports[lr->n_ports - 1];
809     nbrec_logical_router_verify_ports(lr);
810     nbrec_logical_router_set_ports(lr, new_ports, lr->n_ports - 1);
811     free(new_ports);
812
813     /* Delete 'lrport' from the IDL. */
814     nbrec_logical_router_port_delete(lrport);
815 }
816
817 /* Removes lport 'lswitch->ports[idx]'. */
818 static void
819 remove_lport(const struct nbrec_logical_switch *lswitch, size_t idx)
820 {
821     const struct nbrec_logical_port *lport = lswitch->ports[idx];
822
823     /* First remove 'lport' from the array of ports.  This is what will
824      * actually cause the logical port to be deleted when the transaction is
825      * sent to the database server (due to garbage collection). */
826     struct nbrec_logical_port **new_ports
827         = xmemdup(lswitch->ports, sizeof *new_ports * lswitch->n_ports);
828     new_ports[idx] = new_ports[lswitch->n_ports - 1];
829     nbrec_logical_switch_verify_ports(lswitch);
830     nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports - 1);
831     free(new_ports);
832
833     /* Delete 'lport' from the IDL.  This won't have a real effect on the
834      * database server (the IDL will suppress it in fact) but it means that it
835      * won't show up when we iterate with NBREC_LOGICAL_PORT_FOR_EACH later. */
836     nbrec_logical_port_delete(lport);
837 }
838
839 static void
840 nbctl_lport_del(struct ctl_context *ctx)
841 {
842     bool must_exist = !shash_find(&ctx->options, "--if-exists");
843     const struct nbrec_logical_port *lport;
844
845     lport = lport_by_name_or_uuid(ctx, ctx->argv[1], must_exist);
846     if (!lport) {
847         return;
848     }
849
850     /* Find the switch that contains 'lport', then delete it. */
851     const struct nbrec_logical_switch *lswitch;
852     NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, ctx->idl) {
853         for (size_t i = 0; i < lswitch->n_ports; i++) {
854             if (lswitch->ports[i] == lport) {
855                 remove_lport(lswitch, i);
856                 return;
857             }
858         }
859     }
860
861     /* Can't happen because of the database schema. */
862     ctl_fatal("logical port %s is not part of any logical switch",
863               ctx->argv[1]);
864 }
865
866 static void
867 nbctl_lport_list(struct ctl_context *ctx)
868 {
869     const char *id = ctx->argv[1];
870     const struct nbrec_logical_switch *lswitch;
871     struct smap lports;
872     size_t i;
873
874     lswitch = lswitch_by_name_or_uuid(ctx, id, true);
875
876     smap_init(&lports);
877     for (i = 0; i < lswitch->n_ports; i++) {
878         const struct nbrec_logical_port *lport = lswitch->ports[i];
879         smap_add_format(&lports, lport->name, UUID_FMT " (%s)",
880                         UUID_ARGS(&lport->header_.uuid), lport->name);
881     }
882     const struct smap_node **nodes = smap_sort(&lports);
883     for (i = 0; i < smap_count(&lports); i++) {
884         const struct smap_node *node = nodes[i];
885         ds_put_format(&ctx->output, "%s\n", node->value);
886     }
887     smap_destroy(&lports);
888     free(nodes);
889 }
890
891 static void
892 nbctl_lport_get_parent(struct ctl_context *ctx)
893 {
894     const struct nbrec_logical_port *lport;
895
896     lport = lport_by_name_or_uuid(ctx, ctx->argv[1], true);
897     if (lport->parent_name) {
898         ds_put_format(&ctx->output, "%s\n", lport->parent_name);
899     }
900 }
901
902 static void
903 nbctl_lport_get_tag(struct ctl_context *ctx)
904 {
905     const struct nbrec_logical_port *lport;
906
907     lport = lport_by_name_or_uuid(ctx, ctx->argv[1], true);
908     if (lport->n_tag > 0) {
909         ds_put_format(&ctx->output, "%"PRId64"\n", lport->tag[0]);
910     }
911 }
912
913 /* Set the MAC address of lrport. */
914 static void
915 nbctl_lrport_set_mac(struct ctl_context *ctx)
916 {
917     struct eth_addr ea;
918     const char *id = ctx->argv[1];
919     const struct nbrec_logical_router_port *lrport;
920
921     lrport = lrport_by_name_or_uuid(ctx, id, true);
922
923     const char *mac = ctx->argc > 2 ? ctx->argv[2] : "";
924     if (mac[0] && !ovs_scan(ctx->argv[2], ETH_ADDR_SCAN_FMT,
925                             ETH_ADDR_SCAN_ARGS(ea))) {
926         ctl_fatal("%s: invalid MAC address format", mac);
927         return;
928     }
929
930     nbrec_logical_router_port_set_mac(lrport, mac);
931 }
932
933 static void
934 nbctl_lport_set_addresses(struct ctl_context *ctx)
935 {
936     const char *id = ctx->argv[1];
937     const struct nbrec_logical_port *lport;
938
939     lport = lport_by_name_or_uuid(ctx, id, true);
940
941     int i;
942     for (i = 2; i < ctx->argc; i++) {
943         struct eth_addr ea;
944
945         if (strcmp(ctx->argv[i], "unknown")
946             && !ovs_scan(ctx->argv[i], ETH_ADDR_SCAN_FMT,
947                          ETH_ADDR_SCAN_ARGS(ea))) {
948             ctl_fatal("%s: Invalid address format. See ovn-nb(5). "
949                       "Hint: An Ethernet address must be "
950                       "listed before an IP address, together as a single "
951                       "argument.", ctx->argv[i]);
952         }
953     }
954
955     nbrec_logical_port_set_addresses(lport,
956             (const char **) ctx->argv + 2, ctx->argc - 2);
957 }
958
959 /* Following function prints the mac address of the lrport. */
960 static void
961 nbctl_lrport_get_mac(struct ctl_context *ctx)
962 {
963     const char *id = ctx->argv[1];
964     const struct nbrec_logical_router_port *lrport;
965
966     lrport = lrport_by_name_or_uuid(ctx, id, true);
967     if (!lrport) {
968         return;
969     }
970     ds_put_format(&ctx->output, "%s\n", lrport->mac);
971 }
972
973 static void
974 nbctl_lport_get_addresses(struct ctl_context *ctx)
975 {
976     const char *id = ctx->argv[1];
977     const struct nbrec_logical_port *lport;
978     struct svec addresses;
979     const char *mac;
980     size_t i;
981
982     lport = lport_by_name_or_uuid(ctx, id, true);
983
984     svec_init(&addresses);
985     for (i = 0; i < lport->n_addresses; i++) {
986         svec_add(&addresses, lport->addresses[i]);
987     }
988     svec_sort(&addresses);
989     SVEC_FOR_EACH(i, mac, &addresses) {
990         ds_put_format(&ctx->output, "%s\n", mac);
991     }
992     svec_destroy(&addresses);
993 }
994
995 static void
996 nbctl_lport_set_port_security(struct ctl_context *ctx)
997 {
998     const char *id = ctx->argv[1];
999     const struct nbrec_logical_port *lport;
1000
1001     lport = lport_by_name_or_uuid(ctx, id, true);
1002     nbrec_logical_port_set_port_security(lport,
1003             (const char **) ctx->argv + 2, ctx->argc - 2);
1004 }
1005
1006 static void
1007 nbctl_lport_get_port_security(struct ctl_context *ctx)
1008 {
1009     const char *id = ctx->argv[1];
1010     const struct nbrec_logical_port *lport;
1011     struct svec addrs;
1012     const char *addr;
1013     size_t i;
1014
1015     lport = lport_by_name_or_uuid(ctx, id, true);
1016     svec_init(&addrs);
1017     for (i = 0; i < lport->n_port_security; i++) {
1018         svec_add(&addrs, lport->port_security[i]);
1019     }
1020     svec_sort(&addrs);
1021     SVEC_FOR_EACH(i, addr, &addrs) {
1022         ds_put_format(&ctx->output, "%s\n", addr);
1023     }
1024     svec_destroy(&addrs);
1025 }
1026
1027 static void
1028 nbctl_lport_get_up(struct ctl_context *ctx)
1029 {
1030     const char *id = ctx->argv[1];
1031     const struct nbrec_logical_port *lport;
1032
1033     lport = lport_by_name_or_uuid(ctx, id, true);
1034     ds_put_format(&ctx->output,
1035                   "%s\n", (lport->up && *lport->up) ? "up" : "down");
1036 }
1037
1038 static bool
1039 parse_enabled(const char *state)
1040 {
1041     if (!strcasecmp(state, "enabled")) {
1042         return true;
1043     } else if (!strcasecmp(state, "disabled")) {
1044         return false;
1045     } else {
1046         ctl_fatal("%s: state must be \"enabled\" or \"disabled\"", state);
1047     }
1048 }
1049
1050 /* Set the lrport admin-enabled state. */
1051 static void
1052 nbctl_lrport_set_enabled(struct ctl_context *ctx)
1053 {
1054     const char *id = ctx->argv[1];
1055     const char *state = ctx->argv[2];
1056     const struct nbrec_logical_router_port *lrport;
1057
1058     lrport = lrport_by_name_or_uuid(ctx, id, true);
1059     if (!lrport) {
1060         return;
1061     }
1062
1063     bool enabled = parse_enabled(state);
1064     nbrec_logical_router_port_set_enabled(lrport, &enabled, 1);
1065 }
1066
1067 static void
1068 nbctl_lport_set_enabled(struct ctl_context *ctx)
1069 {
1070     const char *id = ctx->argv[1];
1071     const char *state = ctx->argv[2];
1072     const struct nbrec_logical_port *lport;
1073
1074     lport = lport_by_name_or_uuid(ctx, id, true);
1075     bool enabled = parse_enabled(state);
1076     nbrec_logical_port_set_enabled(lport, &enabled, 1);
1077 }
1078
1079 /* Print admin-enabled state for lrport. */
1080 static void
1081 nbctl_lrport_get_enabled(struct ctl_context *ctx)
1082 {
1083     const char *id = ctx->argv[1];
1084     const struct nbrec_logical_router_port *lrport;
1085
1086     lrport = lrport_by_name_or_uuid(ctx, id, true);
1087     if (!lrport) {
1088         return;
1089     }
1090
1091     ds_put_format(&ctx->output, "%s\n",
1092                   !lrport->enabled ||
1093                   *lrport->enabled ? "enabled" : "disabled");
1094 }
1095
1096 static void
1097 nbctl_lport_get_enabled(struct ctl_context *ctx)
1098 {
1099     const char *id = ctx->argv[1];
1100     const struct nbrec_logical_port *lport;
1101
1102     lport = lport_by_name_or_uuid(ctx, id, true);
1103     ds_put_format(&ctx->output, "%s\n",
1104                   !lport->enabled || *lport->enabled ? "enabled" : "disabled");
1105 }
1106
1107 static void
1108 nbctl_lport_set_type(struct ctl_context *ctx)
1109 {
1110     const char *id = ctx->argv[1];
1111     const char *type = ctx->argv[2];
1112     const struct nbrec_logical_port *lport;
1113
1114     lport = lport_by_name_or_uuid(ctx, id, true);
1115     nbrec_logical_port_set_type(lport, type);
1116 }
1117
1118 static void
1119 nbctl_lport_get_type(struct ctl_context *ctx)
1120 {
1121     const char *id = ctx->argv[1];
1122     const struct nbrec_logical_port *lport;
1123
1124     lport = lport_by_name_or_uuid(ctx, id, true);
1125     ds_put_format(&ctx->output, "%s\n", lport->type);
1126 }
1127
1128 static void
1129 nbctl_lport_set_options(struct ctl_context *ctx)
1130 {
1131     const char *id = ctx->argv[1];
1132     const struct nbrec_logical_port *lport;
1133     size_t i;
1134     struct smap options = SMAP_INITIALIZER(&options);
1135
1136     lport = lport_by_name_or_uuid(ctx, id, true);
1137     for (i = 2; i < ctx->argc; i++) {
1138         char *key, *value;
1139         value = xstrdup(ctx->argv[i]);
1140         key = strsep(&value, "=");
1141         if (value) {
1142             smap_add(&options, key, value);
1143         }
1144         free(key);
1145     }
1146
1147     nbrec_logical_port_set_options(lport, &options);
1148
1149     smap_destroy(&options);
1150 }
1151
1152 static void
1153 nbctl_lport_get_options(struct ctl_context *ctx)
1154 {
1155     const char *id = ctx->argv[1];
1156     const struct nbrec_logical_port *lport;
1157     struct smap_node *node;
1158
1159     lport = lport_by_name_or_uuid(ctx, id, true);
1160     SMAP_FOR_EACH(node, &lport->options) {
1161         ds_put_format(&ctx->output, "%s=%s\n", node->key, node->value);
1162     }
1163 }
1164
1165 enum {
1166     DIR_FROM_LPORT,
1167     DIR_TO_LPORT
1168 };
1169
1170 static int
1171 dir_encode(const char *dir)
1172 {
1173     if (!strcmp(dir, "from-lport")) {
1174         return DIR_FROM_LPORT;
1175     } else if (!strcmp(dir, "to-lport")) {
1176         return DIR_TO_LPORT;
1177     }
1178
1179     OVS_NOT_REACHED();
1180 }
1181
1182 static int
1183 acl_cmp(const void *acl1_, const void *acl2_)
1184 {
1185     const struct nbrec_acl *const *acl1p = acl1_;
1186     const struct nbrec_acl *const *acl2p = acl2_;
1187     const struct nbrec_acl *acl1 = *acl1p;
1188     const struct nbrec_acl *acl2 = *acl2p;
1189
1190     int dir1 = dir_encode(acl1->direction);
1191     int dir2 = dir_encode(acl2->direction);
1192
1193     if (dir1 != dir2) {
1194         return dir1 < dir2 ? -1 : 1;
1195     } else if (acl1->priority != acl2->priority) {
1196         return acl1->priority > acl2->priority ? -1 : 1;
1197     } else {
1198         return strcmp(acl1->match, acl2->match);
1199     }
1200 }
1201
1202 static void
1203 nbctl_acl_list(struct ctl_context *ctx)
1204 {
1205     const struct nbrec_logical_switch *lswitch;
1206     const struct nbrec_acl **acls;
1207     size_t i;
1208
1209     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1], true);
1210
1211     acls = xmalloc(sizeof *acls * lswitch->n_acls);
1212     for (i = 0; i < lswitch->n_acls; i++) {
1213         acls[i] = lswitch->acls[i];
1214     }
1215
1216     qsort(acls, lswitch->n_acls, sizeof *acls, acl_cmp);
1217
1218     for (i = 0; i < lswitch->n_acls; i++) {
1219         const struct nbrec_acl *acl = acls[i];
1220         ds_put_format(&ctx->output, "%10s %5"PRId64" (%s) %s%s\n",
1221                       acl->direction, acl->priority,
1222                       acl->match, acl->action, acl->log ? " log" : "");
1223     }
1224
1225     free(acls);
1226 }
1227
1228 static const char *
1229 parse_direction(const char *arg)
1230 {
1231     /* Validate direction.  Only require the first letter. */
1232     if (arg[0] == 't') {
1233         return "to-lport";
1234     } else if (arg[0] == 'f') {
1235         return "from-lport";
1236     } else {
1237         ctl_fatal("%s: direction must be \"to-lport\" or \"from-lport\"", arg);
1238     }
1239 }
1240
1241 static int
1242 parse_priority(const char *arg)
1243 {
1244     /* Validate priority. */
1245     int64_t priority;
1246     if (!ovs_scan(arg, "%"SCNd64, &priority)
1247         || priority < 0 || priority > 32767) {
1248         ctl_fatal("%s: priority must in range 0...32767", arg);
1249     }
1250     return priority;
1251 }
1252
1253 static void
1254 nbctl_acl_add(struct ctl_context *ctx)
1255 {
1256     const struct nbrec_logical_switch *lswitch;
1257     const char *action = ctx->argv[5];
1258
1259     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1], true);
1260
1261     const char *direction = parse_direction(ctx->argv[2]);
1262     int64_t priority = parse_priority(ctx->argv[3]);
1263
1264     /* Validate action. */
1265     if (strcmp(action, "allow") && strcmp(action, "allow-related")
1266         && strcmp(action, "drop") && strcmp(action, "reject")) {
1267         ctl_fatal("%s: action must be one of \"allow\", \"allow-related\", "
1268                   "\"drop\", and \"reject\"", action);
1269         return;
1270     }
1271
1272     /* Create the acl. */
1273     struct nbrec_acl *acl = nbrec_acl_insert(ctx->txn);
1274     nbrec_acl_set_priority(acl, priority);
1275     nbrec_acl_set_direction(acl, direction);
1276     nbrec_acl_set_match(acl, ctx->argv[4]);
1277     nbrec_acl_set_action(acl, action);
1278     if (shash_find(&ctx->options, "--log") != NULL) {
1279         nbrec_acl_set_log(acl, true);
1280     }
1281
1282     /* Insert the acl into the logical switch. */
1283     nbrec_logical_switch_verify_acls(lswitch);
1284     struct nbrec_acl **new_acls = xmalloc(sizeof *new_acls *
1285                                           (lswitch->n_acls + 1));
1286     memcpy(new_acls, lswitch->acls, sizeof *new_acls * lswitch->n_acls);
1287     new_acls[lswitch->n_acls] = acl;
1288     nbrec_logical_switch_set_acls(lswitch, new_acls, lswitch->n_acls + 1);
1289     free(new_acls);
1290 }
1291
1292 static void
1293 nbctl_acl_del(struct ctl_context *ctx)
1294 {
1295     const struct nbrec_logical_switch *lswitch;
1296     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1], true);
1297
1298     if (ctx->argc != 2 && ctx->argc != 3 && ctx->argc != 5) {
1299         ctl_fatal("cannot specify priority without match");
1300     }
1301
1302     if (ctx->argc == 2) {
1303         /* If direction, priority, and match are not specified, delete
1304          * all ACLs. */
1305         nbrec_logical_switch_verify_acls(lswitch);
1306         nbrec_logical_switch_set_acls(lswitch, NULL, 0);
1307         return;
1308     }
1309
1310     const char *direction = parse_direction(ctx->argv[2]);
1311
1312     /* If priority and match are not specified, delete all ACLs with the
1313      * specified direction. */
1314     if (ctx->argc == 3) {
1315         struct nbrec_acl **new_acls
1316             = xmalloc(sizeof *new_acls * lswitch->n_acls);
1317
1318         int n_acls = 0;
1319         for (size_t i = 0; i < lswitch->n_acls; i++) {
1320             if (strcmp(direction, lswitch->acls[i]->direction)) {
1321                 new_acls[n_acls++] = lswitch->acls[i];
1322             }
1323         }
1324
1325         nbrec_logical_switch_verify_acls(lswitch);
1326         nbrec_logical_switch_set_acls(lswitch, new_acls, n_acls);
1327         free(new_acls);
1328         return;
1329     }
1330
1331     int64_t priority = parse_priority(ctx->argv[3]);
1332
1333     /* Remove the matching rule. */
1334     for (size_t i = 0; i < lswitch->n_acls; i++) {
1335         struct nbrec_acl *acl = lswitch->acls[i];
1336
1337         if (priority == acl->priority && !strcmp(ctx->argv[4], acl->match) &&
1338              !strcmp(direction, acl->direction)) {
1339             struct nbrec_acl **new_acls
1340                 = xmemdup(lswitch->acls, sizeof *new_acls * lswitch->n_acls);
1341             new_acls[i] = lswitch->acls[lswitch->n_acls - 1];
1342             nbrec_logical_switch_verify_acls(lswitch);
1343             nbrec_logical_switch_set_acls(lswitch, new_acls,
1344                                           lswitch->n_acls - 1);
1345             free(new_acls);
1346             return;
1347         }
1348     }
1349 }
1350 \f
1351 static void
1352 nbctl_lr_add(struct ctl_context *ctx)
1353 {
1354     const char *lr_name = ctx->argc == 2 ? ctx->argv[1] : NULL;
1355
1356     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1357     bool add_duplicate = shash_find(&ctx->options, "--add-duplicate") != NULL;
1358     if (may_exist && add_duplicate) {
1359         ctl_fatal("--may-exist and --add-duplicate may not be used together");
1360     }
1361
1362     if (lr_name) {
1363         if (!add_duplicate) {
1364             const struct nbrec_logical_router *lr;
1365             NBREC_LOGICAL_ROUTER_FOR_EACH (lr, ctx->idl) {
1366                 if (!strcmp(lr->name, lr_name)) {
1367                     if (may_exist) {
1368                         return;
1369                     }
1370                     ctl_fatal("%s: a router with this name already exists",
1371                               lr_name);
1372                 }
1373             }
1374         }
1375     } else if (may_exist) {
1376         ctl_fatal("--may-exist requires specifying a name");
1377     } else if (add_duplicate) {
1378         ctl_fatal("--add-duplicate requires specifying a name");
1379     }
1380
1381     struct nbrec_logical_router *lr;
1382     lr = nbrec_logical_router_insert(ctx->txn);
1383     if (lr_name) {
1384         nbrec_logical_router_set_name(lr, lr_name);
1385     }
1386 }
1387
1388 static void
1389 nbctl_lr_del(struct ctl_context *ctx)
1390 {
1391     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1392     const char *id = ctx->argv[1];
1393     const struct nbrec_logical_router *lr;
1394
1395     lr = lr_by_name_or_uuid(ctx, id, must_exist);
1396     if (!lr) {
1397         return;
1398     }
1399
1400     nbrec_logical_router_delete(lr);
1401 }
1402
1403 static void
1404 nbctl_lr_list(struct ctl_context *ctx)
1405 {
1406     const struct nbrec_logical_router *lr;
1407     struct smap lrs;
1408
1409     smap_init(&lrs);
1410     NBREC_LOGICAL_ROUTER_FOR_EACH(lr, ctx->idl) {
1411         smap_add_format(&lrs, lr->name, UUID_FMT " (%s)",
1412                         UUID_ARGS(&lr->header_.uuid), lr->name);
1413     }
1414     const struct smap_node **nodes = smap_sort(&lrs);
1415     for (size_t i = 0; i < smap_count(&lrs); i++) {
1416         const struct smap_node *node = nodes[i];
1417         ds_put_format(&ctx->output, "%s\n", node->value);
1418     }
1419     smap_destroy(&lrs);
1420     free(nodes);
1421 }
1422 \f
1423 static const struct ctl_table_class tables[] = {
1424     {&nbrec_table_logical_switch,
1425      {{&nbrec_table_logical_switch, &nbrec_logical_switch_col_name, NULL},
1426       {NULL, NULL, NULL}}},
1427
1428     {&nbrec_table_logical_port,
1429      {{&nbrec_table_logical_port, &nbrec_logical_port_col_name, NULL},
1430       {NULL, NULL, NULL}}},
1431
1432     {&nbrec_table_acl,
1433      {{NULL, NULL, NULL},
1434       {NULL, NULL, NULL}}},
1435
1436     {&nbrec_table_logical_router,
1437      {{&nbrec_table_logical_router, &nbrec_logical_router_col_name, NULL},
1438       {NULL, NULL, NULL}}},
1439
1440     {&nbrec_table_logical_router_port,
1441      {{&nbrec_table_logical_router_port, &nbrec_logical_router_port_col_name,
1442        NULL},
1443       {NULL, NULL, NULL}}},
1444
1445     {&nbrec_table_logical_router_static_route,
1446      {{&nbrec_table_logical_router_static_route, NULL,
1447        NULL},
1448       {NULL, NULL, NULL}}},
1449
1450     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
1451 };
1452 \f
1453 static void
1454 run_prerequisites(struct ctl_command *commands, size_t n_commands,
1455                   struct ovsdb_idl *idl)
1456 {
1457     struct ctl_command *c;
1458
1459     for (c = commands; c < &commands[n_commands]; c++) {
1460         if (c->syntax->prerequisites) {
1461             struct ctl_context ctx;
1462
1463             ds_init(&c->output);
1464             c->table = NULL;
1465
1466             ctl_context_init(&ctx, c, idl, NULL, NULL, NULL);
1467             (c->syntax->prerequisites)(&ctx);
1468             ctl_context_done(&ctx, c);
1469
1470             ovs_assert(!c->output.string);
1471             ovs_assert(!c->table);
1472         }
1473     }
1474 }
1475
1476 static bool
1477 do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
1478          struct ovsdb_idl *idl)
1479 {
1480     struct ovsdb_idl_txn *txn;
1481     enum ovsdb_idl_txn_status status;
1482     struct ovsdb_symbol_table *symtab;
1483     struct ctl_context ctx;
1484     struct ctl_command *c;
1485     struct shash_node *node;
1486     char *error = NULL;
1487
1488     txn = the_idl_txn = ovsdb_idl_txn_create(idl);
1489     if (dry_run) {
1490         ovsdb_idl_txn_set_dry_run(txn);
1491     }
1492
1493     ovsdb_idl_txn_add_comment(txn, "ovs-nbctl: %s", args);
1494
1495     symtab = ovsdb_symbol_table_create();
1496     for (c = commands; c < &commands[n_commands]; c++) {
1497         ds_init(&c->output);
1498         c->table = NULL;
1499     }
1500     ctl_context_init(&ctx, NULL, idl, txn, symtab, NULL);
1501     for (c = commands; c < &commands[n_commands]; c++) {
1502         ctl_context_init_command(&ctx, c);
1503         if (c->syntax->run) {
1504             (c->syntax->run)(&ctx);
1505         }
1506         ctl_context_done_command(&ctx, c);
1507
1508         if (ctx.try_again) {
1509             ctl_context_done(&ctx, NULL);
1510             goto try_again;
1511         }
1512     }
1513     ctl_context_done(&ctx, NULL);
1514
1515     SHASH_FOR_EACH (node, &symtab->sh) {
1516         struct ovsdb_symbol *symbol = node->data;
1517         if (!symbol->created) {
1518             ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
1519                       "with \"-- --id=%s create ...\")",
1520                       node->name, node->name);
1521         }
1522         if (!symbol->strong_ref) {
1523             if (!symbol->weak_ref) {
1524                 VLOG_WARN("row id \"%s\" was created but no reference to it "
1525                           "was inserted, so it will not actually appear in "
1526                           "the database", node->name);
1527             } else {
1528                 VLOG_WARN("row id \"%s\" was created but only a weak "
1529                           "reference to it was inserted, so it will not "
1530                           "actually appear in the database", node->name);
1531             }
1532         }
1533     }
1534
1535     status = ovsdb_idl_txn_commit_block(txn);
1536     if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
1537         for (c = commands; c < &commands[n_commands]; c++) {
1538             if (c->syntax->postprocess) {
1539                 ctl_context_init(&ctx, c, idl, txn, symtab, NULL);
1540                 (c->syntax->postprocess)(&ctx);
1541                 ctl_context_done(&ctx, c);
1542             }
1543         }
1544     }
1545     error = xstrdup(ovsdb_idl_txn_get_error(txn));
1546
1547     switch (status) {
1548     case TXN_UNCOMMITTED:
1549     case TXN_INCOMPLETE:
1550         OVS_NOT_REACHED();
1551
1552     case TXN_ABORTED:
1553         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1554         ctl_fatal("transaction aborted");
1555
1556     case TXN_UNCHANGED:
1557     case TXN_SUCCESS:
1558         break;
1559
1560     case TXN_TRY_AGAIN:
1561         goto try_again;
1562
1563     case TXN_ERROR:
1564         ctl_fatal("transaction error: %s", error);
1565
1566     case TXN_NOT_LOCKED:
1567         /* Should not happen--we never call ovsdb_idl_set_lock(). */
1568         ctl_fatal("database not locked");
1569
1570     default:
1571         OVS_NOT_REACHED();
1572     }
1573     free(error);
1574
1575     ovsdb_symbol_table_destroy(symtab);
1576
1577     for (c = commands; c < &commands[n_commands]; c++) {
1578         struct ds *ds = &c->output;
1579
1580         if (c->table) {
1581             table_print(c->table, &table_style);
1582         } else if (oneline) {
1583             size_t j;
1584
1585             ds_chomp(ds, '\n');
1586             for (j = 0; j < ds->length; j++) {
1587                 int ch = ds->string[j];
1588                 switch (ch) {
1589                 case '\n':
1590                     fputs("\\n", stdout);
1591                     break;
1592
1593                 case '\\':
1594                     fputs("\\\\", stdout);
1595                     break;
1596
1597                 default:
1598                     putchar(ch);
1599                 }
1600             }
1601             putchar('\n');
1602         } else {
1603             fputs(ds_cstr(ds), stdout);
1604         }
1605         ds_destroy(&c->output);
1606         table_destroy(c->table);
1607         free(c->table);
1608
1609         shash_destroy_free_data(&c->options);
1610     }
1611     free(commands);
1612     ovsdb_idl_txn_destroy(txn);
1613     ovsdb_idl_destroy(idl);
1614
1615     return true;
1616
1617 try_again:
1618     /* Our transaction needs to be rerun, or a prerequisite was not met.  Free
1619      * resources and return so that the caller can try again. */
1620     if (txn) {
1621         ovsdb_idl_txn_abort(txn);
1622         ovsdb_idl_txn_destroy(txn);
1623         the_idl_txn = NULL;
1624     }
1625     ovsdb_symbol_table_destroy(symtab);
1626     for (c = commands; c < &commands[n_commands]; c++) {
1627         ds_destroy(&c->output);
1628         table_destroy(c->table);
1629         free(c->table);
1630     }
1631     free(error);
1632     return false;
1633 }
1634
1635 /* Frees the current transaction and the underlying IDL and then calls
1636  * exit(status).
1637  *
1638  * Freeing the transaction and the IDL is not strictly necessary, but it makes
1639  * for a clean memory leak report from valgrind in the normal case.  That makes
1640  * it easier to notice real memory leaks. */
1641 static void
1642 nbctl_exit(int status)
1643 {
1644     if (the_idl_txn) {
1645         ovsdb_idl_txn_abort(the_idl_txn);
1646         ovsdb_idl_txn_destroy(the_idl_txn);
1647     }
1648     ovsdb_idl_destroy(the_idl);
1649     exit(status);
1650 }
1651
1652 /* Print a list of lrports. */
1653 static void
1654 nbctl_lrport_list(struct ctl_context *ctx)
1655 {
1656     const char *id = ctx->argv[1];
1657     const struct nbrec_logical_router *lr;
1658     struct smap lports;
1659     size_t i;
1660
1661     lr = lr_by_name_or_uuid(ctx, id, true);
1662
1663     smap_init(&lports);
1664     for (i = 0; i < lr->n_ports; i++) {
1665         const struct nbrec_logical_router_port *lport = lr->ports[i];
1666         smap_add_format(&lports, lport->name, UUID_FMT " (%s)",
1667                         UUID_ARGS(&lport->header_.uuid), lport->name);
1668     }
1669     const struct smap_node **nodes = smap_sort(&lports);
1670     for (i = 0; i < smap_count(&lports); i++) {
1671         const struct smap_node *node = nodes[i];
1672         ds_put_format(&ctx->output, "%s\n", node->value);
1673     }
1674     smap_destroy(&lports);
1675     free(nodes);
1676 }
1677
1678 /* Add an lrport to the logical router. */
1679 static void
1680 nbctl_lrport_add(struct ctl_context *ctx)
1681 {
1682     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1683
1684     const struct nbrec_logical_router *lr;
1685     lr = lr_by_name_or_uuid(ctx, ctx->argv[1], true);
1686
1687     const char *lrport_name = ctx->argv[2];
1688     const struct nbrec_logical_router_port *lrport;
1689
1690     lrport = lrport_by_name_or_uuid(ctx, lrport_name, false);
1691     if (lrport) {
1692         if (!may_exist) {
1693             ctl_fatal("%s: an lrport with this name already exists",
1694                       lrport_name);
1695         }
1696
1697         const struct nbrec_logical_router *bound_lr;
1698         bound_lr = lrport_to_lr(ctx->idl, lrport);
1699         if (bound_lr != lr) {
1700             char uuid_s[UUID_LEN + 1];
1701             ctl_fatal("%s: lrport already exists but in router %s",
1702                       lrport_name,
1703                       lr_get_name(bound_lr, uuid_s, sizeof uuid_s));
1704         }
1705
1706         return;
1707     }
1708
1709     /* Create the logical router port. */
1710     lrport = nbrec_logical_router_port_insert(ctx->txn);
1711     nbrec_logical_router_port_set_name(lrport, ctx->argv[2]);
1712
1713     /* Insert the logical port into the logical router. */
1714     nbrec_logical_router_verify_ports(lr);
1715     struct nbrec_logical_router_port **new_ports = xmalloc(sizeof *new_ports *
1716                                                     (lr->n_ports + 1));
1717     memcpy(new_ports, lr->ports, sizeof *new_ports * lr->n_ports);
1718     new_ports[lr->n_ports] = CONST_CAST(
1719         struct nbrec_logical_router_port *, lrport);
1720     nbrec_logical_router_set_ports(lr, new_ports, lr->n_ports + 1);
1721     free(new_ports);
1722 }
1723
1724 /* Deletes an lrport from a logical router. */
1725 static void
1726 nbctl_lrport_del(struct ctl_context *ctx)
1727 {
1728     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1729     const struct nbrec_logical_router_port *lrport;
1730
1731     lrport = lrport_by_name_or_uuid(ctx, ctx->argv[1], must_exist);
1732     if (!lrport) {
1733         return;
1734     }
1735
1736     /* Find the router that contains 'lrport', then delete it. */
1737     const struct nbrec_logical_router *lr;
1738     NBREC_LOGICAL_ROUTER_FOR_EACH (lr, ctx->idl) {
1739         for (size_t i = 0; i < lr->n_ports; i++) {
1740             if (lr->ports[i] == lrport) {
1741                 remove_lrport(lr, i);
1742                 return;
1743             }
1744         }
1745     }
1746
1747     ctl_fatal("logical router port %s is not part of any logical router",
1748               ctx->argv[1]);
1749 }
1750
1751 static const struct ctl_command_syntax nbctl_commands[] = {
1752     { "show", 0, 1, "[LSWITCH]", NULL, nbctl_show, NULL, "", RO },
1753
1754     /* lswitch commands. */
1755     { "lswitch-add", 0, 1, "[LSWITCH]", NULL, nbctl_lswitch_add,
1756       NULL, "--may-exist,--add-duplicate", RW },
1757     { "lswitch-del", 1, 1, "LSWITCH", NULL, nbctl_lswitch_del,
1758       NULL, "--if-exists", RW },
1759     { "lswitch-list", 0, 0, "", NULL, nbctl_lswitch_list, NULL, "", RO },
1760
1761     /* acl commands. */
1762     { "acl-add", 5, 5, "LSWITCH DIRECTION PRIORITY MATCH ACTION", NULL,
1763       nbctl_acl_add, NULL, "--log", RW },
1764     { "acl-del", 1, 4, "LSWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
1765       nbctl_acl_del, NULL, "", RW },
1766     { "acl-list", 1, 1, "LSWITCH", NULL, nbctl_acl_list, NULL, "", RO },
1767
1768     /* lrport commands. */
1769     { "lrport-add", 2, 2, "ROUTER LRPORT", NULL, nbctl_lrport_add,
1770       NULL, "--may-exist", RW },
1771     { "lrport-del", 1, 1, "LRPORT", NULL, nbctl_lrport_del, NULL, "", RO },
1772     { "lrport-list", 1, 1, "ROUTER", NULL, nbctl_lrport_list, NULL, "", RO },
1773     { "lrport-set-mac-address", 1, 2, "LRPORT [ADDRESS]", NULL,
1774       nbctl_lrport_set_mac, NULL, "", RW },
1775     { "lrport-get-mac-address", 1, 1, "LRPORT", NULL,
1776       nbctl_lrport_get_mac, NULL,
1777       "", RO },
1778     { "lrport-set-enabled", 2, 2, "LRPORT STATE", NULL,
1779       nbctl_lrport_set_enabled, NULL, "", RW },
1780     { "lrport-get-enabled", 1, 1, "LRPORT", NULL,
1781       nbctl_lrport_get_enabled, NULL, "", RO },
1782
1783     /* lport commands. */
1784     { "lport-add", 2, 4, "LSWITCH LPORT [PARENT] [TAG]", NULL, nbctl_lport_add,
1785       NULL, "--may-exist", RW },
1786     { "lport-del", 1, 1, "LPORT", NULL, nbctl_lport_del, NULL, "--if-exists",
1787       RW },
1788     { "lport-list", 1, 1, "LSWITCH", NULL, nbctl_lport_list, NULL, "", RO },
1789     { "lport-get-parent", 1, 1, "LPORT", NULL, nbctl_lport_get_parent, NULL,
1790       "", RO },
1791     { "lport-get-tag", 1, 1, "LPORT", NULL, nbctl_lport_get_tag, NULL, "",
1792       RO },
1793     { "lport-set-addresses", 1, INT_MAX, "LPORT [ADDRESS]...", NULL,
1794       nbctl_lport_set_addresses, NULL, "", RW },
1795     { "lport-get-addresses", 1, 1, "LPORT", NULL,
1796       nbctl_lport_get_addresses, NULL,
1797       "", RO },
1798     { "lport-set-port-security", 0, INT_MAX, "LPORT [ADDRS]...", NULL,
1799       nbctl_lport_set_port_security, NULL, "", RW },
1800     { "lport-get-port-security", 1, 1, "LPORT", NULL,
1801       nbctl_lport_get_port_security, NULL, "", RO },
1802     { "lport-get-up", 1, 1, "LPORT", NULL, nbctl_lport_get_up, NULL, "", RO },
1803     { "lport-set-enabled", 2, 2, "LPORT STATE", NULL, nbctl_lport_set_enabled,
1804       NULL, "", RW },
1805     { "lport-get-enabled", 1, 1, "LPORT", NULL, nbctl_lport_get_enabled, NULL,
1806       "", RO },
1807     { "lport-set-type", 2, 2, "LPORT TYPE", NULL, nbctl_lport_set_type, NULL,
1808       "", RW },
1809     { "lport-get-type", 1, 1, "LPORT", NULL, nbctl_lport_get_type, NULL, "",
1810       RO },
1811     { "lport-set-options", 1, INT_MAX, "LPORT KEY=VALUE [KEY=VALUE]...", NULL,
1812       nbctl_lport_set_options, NULL, "", RW },
1813     { "lport-get-options", 1, 1, "LPORT", NULL, nbctl_lport_get_options, NULL,
1814       "", RO },
1815
1816     /* logical router commands. */
1817     { "lr-add", 0, 1, "[ROUTER]", NULL, nbctl_lr_add, NULL,
1818       "--may-exist,--add-duplicate", RW },
1819     { "lr-del", 1, 1, "ROUTER", NULL, nbctl_lr_del, NULL, "--if-exists", RW },
1820     { "lr-list", 0, 0, "", NULL, nbctl_lr_list, NULL, "", RO },
1821
1822     {NULL, 0, 0, NULL, NULL, NULL, NULL, "", RO},
1823 };
1824
1825 /* Registers nbctl and common db commands. */
1826 static void
1827 nbctl_cmd_init(void)
1828 {
1829     ctl_init(tables, NULL, nbctl_exit);
1830     ctl_register_commands(nbctl_commands);
1831 }