ovn: Make it possible for CMS to detect when the OVN system is up-to-date.
[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 "openvswitch/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 "sset.h"
33 #include "stream.h"
34 #include "stream-ssl.h"
35 #include "svec.h"
36 #include "table.h"
37 #include "timeval.h"
38 #include "util.h"
39 #include "openvswitch/vlog.h"
40
41 VLOG_DEFINE_THIS_MODULE(nbctl);
42
43 /* --db: The database server to contact. */
44 static const char *db;
45
46 /* --oneline: Write each command's output as a single line? */
47 static bool oneline;
48
49 /* --dry-run: Do not commit any changes. */
50 static bool dry_run;
51
52 /* --wait=TYPE: Wait for configuration change to take effect? */
53 enum nbctl_wait_type {
54     NBCTL_WAIT_NONE,            /* Do not wait. */
55     NBCTL_WAIT_SB,              /* Wait for southbound database updates. */
56     NBCTL_WAIT_HV               /* Wait for hypervisors to catch up. */
57 };
58 static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
59
60 /* --timeout: Time to wait for a connection to 'db'. */
61 static int timeout;
62
63 /* Format for table output. */
64 static struct table_style table_style = TABLE_STYLE_DEFAULT;
65
66 /* The IDL we're using and the current transaction, if any.
67  * This is for use by nbctl_exit() only, to allow it to clean up.
68  * Other code should use its context arguments. */
69 static struct ovsdb_idl *the_idl;
70 static struct ovsdb_idl_txn *the_idl_txn;
71 OVS_NO_RETURN static void nbctl_exit(int status);
72
73 static void nbctl_cmd_init(void);
74 OVS_NO_RETURN static void usage(void);
75 static void parse_options(int argc, char *argv[], struct shash *local_options);
76 static const char *nbctl_default_db(void);
77 static void run_prerequisites(struct ctl_command[], size_t n_commands,
78                               struct ovsdb_idl *);
79 static bool do_nbctl(const char *args, struct ctl_command *, size_t n,
80                      struct ovsdb_idl *);
81 static const struct nbrec_dhcp_options *dhcp_options_get(
82     struct ctl_context *ctx, const char *id, bool must_exist);
83
84 int
85 main(int argc, char *argv[])
86 {
87     struct ovsdb_idl *idl;
88     struct ctl_command *commands;
89     struct shash local_options;
90     unsigned int seqno;
91     size_t n_commands;
92     char *args;
93
94     set_program_name(argv[0]);
95     fatal_ignore_sigpipe();
96     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
97     vlog_set_levels_from_string_assert("reconnect:warn");
98     nbrec_init();
99
100     nbctl_cmd_init();
101
102     /* Log our arguments.  This is often valuable for debugging systems. */
103     args = process_escape_args(argv);
104     VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG,
105          "Called as %s", args);
106
107     /* Parse command line. */
108     shash_init(&local_options);
109     parse_options(argc, argv, &local_options);
110     commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
111                                   &n_commands);
112
113     if (timeout) {
114         time_alarm(timeout);
115     }
116
117     /* Initialize IDL. */
118     idl = the_idl = ovsdb_idl_create(db, &nbrec_idl_class, true, false);
119     run_prerequisites(commands, n_commands, idl);
120
121     /* Execute the commands.
122      *
123      * 'seqno' is the database sequence number for which we last tried to
124      * execute our transaction.  There's no point in trying to commit more than
125      * once for any given sequence number, because if the transaction fails
126      * it's because the database changed and we need to obtain an up-to-date
127      * view of the database before we try the transaction again. */
128     seqno = ovsdb_idl_get_seqno(idl);
129     for (;;) {
130         ovsdb_idl_run(idl);
131         if (!ovsdb_idl_is_alive(idl)) {
132             int retval = ovsdb_idl_get_last_error(idl);
133             ctl_fatal("%s: database connection failed (%s)",
134                         db, ovs_retval_to_string(retval));
135         }
136
137         if (seqno != ovsdb_idl_get_seqno(idl)) {
138             seqno = ovsdb_idl_get_seqno(idl);
139             if (do_nbctl(args, commands, n_commands, idl)) {
140                 free(args);
141                 exit(EXIT_SUCCESS);
142             }
143         }
144
145         if (seqno == ovsdb_idl_get_seqno(idl)) {
146             ovsdb_idl_wait(idl);
147             poll_block();
148         }
149     }
150 }
151
152 static const char *
153 nbctl_default_db(void)
154 {
155     static char *def;
156     if (!def) {
157         def = getenv("OVN_NB_DB");
158         if (!def) {
159             def = xasprintf("unix:%s/ovnnb_db.sock", ovs_rundir());
160         }
161     }
162     return def;
163 }
164
165 static void
166 parse_options(int argc, char *argv[], struct shash *local_options)
167 {
168     enum {
169         OPT_DB = UCHAR_MAX + 1,
170         OPT_NO_SYSLOG,
171         OPT_NO_WAIT,
172         OPT_WAIT,
173         OPT_DRY_RUN,
174         OPT_ONELINE,
175         OPT_LOCAL,
176         OPT_COMMANDS,
177         OPT_OPTIONS,
178         VLOG_OPTION_ENUMS,
179         TABLE_OPTION_ENUMS
180     };
181     static const struct option global_long_options[] = {
182         {"db", required_argument, NULL, OPT_DB},
183         {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
184         {"no-wait", no_argument, NULL, OPT_NO_WAIT},
185         {"wait", required_argument, NULL, OPT_WAIT},
186         {"dry-run", no_argument, NULL, OPT_DRY_RUN},
187         {"oneline", no_argument, NULL, OPT_ONELINE},
188         {"timeout", required_argument, NULL, 't'},
189         {"help", no_argument, NULL, 'h'},
190         {"commands", no_argument, NULL, OPT_COMMANDS},
191         {"options", no_argument, NULL, OPT_OPTIONS},
192         {"version", no_argument, NULL, 'V'},
193         VLOG_LONG_OPTIONS,
194         STREAM_SSL_LONG_OPTIONS,
195         TABLE_LONG_OPTIONS,
196         {NULL, 0, NULL, 0},
197     };
198     const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
199     char *tmp, *short_options;
200
201     struct option *options;
202     size_t allocated_options;
203     size_t n_options;
204     size_t i;
205
206     tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
207     short_options = xasprintf("+%s", tmp);
208     free(tmp);
209
210     /* We want to parse both global and command-specific options here, but
211      * getopt_long() isn't too convenient for the job.  We copy our global
212      * options into a dynamic array, then append all of the command-specific
213      * options. */
214     options = xmemdup(global_long_options, sizeof global_long_options);
215     allocated_options = ARRAY_SIZE(global_long_options);
216     n_options = n_global_long_options;
217     ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
218     table_style.format = TF_LIST;
219
220     for (;;) {
221         int idx;
222         int c;
223
224         c = getopt_long(argc, argv, short_options, options, &idx);
225         if (c == -1) {
226             break;
227         }
228
229         switch (c) {
230         case OPT_DB:
231             db = optarg;
232             break;
233
234         case OPT_ONELINE:
235             oneline = true;
236             break;
237
238         case OPT_NO_SYSLOG:
239             vlog_set_levels(&this_module, VLF_SYSLOG, VLL_WARN);
240             break;
241
242         case OPT_NO_WAIT:
243             wait_type = NBCTL_WAIT_NONE;
244             break;
245
246         case OPT_WAIT:
247             if (!strcmp(optarg, "none")) {
248                 wait_type = NBCTL_WAIT_NONE;
249             } else if (!strcmp(optarg, "sb")) {
250                 wait_type = NBCTL_WAIT_SB;
251             } else if (!strcmp(optarg, "hv")) {
252                 wait_type = NBCTL_WAIT_HV;
253             } else {
254                 ctl_fatal("argument to --wait must be "
255                           "\"none\", \"sb\", or \"hv\"");
256             }
257             break;
258
259         case OPT_DRY_RUN:
260             dry_run = true;
261             break;
262
263         case OPT_LOCAL:
264             if (shash_find(local_options, options[idx].name)) {
265                 ctl_fatal("'%s' option specified multiple times",
266                             options[idx].name);
267             }
268             shash_add_nocopy(local_options,
269                              xasprintf("--%s", options[idx].name),
270                              nullable_xstrdup(optarg));
271             break;
272
273         case 'h':
274             usage();
275             exit(EXIT_SUCCESS);
276
277         case OPT_COMMANDS:
278             ctl_print_commands();
279
280         case OPT_OPTIONS:
281             ctl_print_options(global_long_options);
282
283         case 'V':
284             ovs_print_version(0, 0);
285             printf("DB Schema %s\n", nbrec_get_db_version());
286             exit(EXIT_SUCCESS);
287
288         case 't':
289             timeout = strtoul(optarg, NULL, 10);
290             if (timeout < 0) {
291                 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
292             }
293             break;
294
295         VLOG_OPTION_HANDLERS
296         TABLE_OPTION_HANDLERS(&table_style)
297         STREAM_SSL_OPTION_HANDLERS
298
299         case '?':
300             exit(EXIT_FAILURE);
301
302         default:
303             abort();
304         }
305     }
306     free(short_options);
307
308     if (!db) {
309         db = nbctl_default_db();
310     }
311
312     for (i = n_global_long_options; options[i].name; i++) {
313         free(CONST_CAST(char *, options[i].name));
314     }
315     free(options);
316 }
317
318 static void
319 usage(void)
320 {
321     printf("\
322 %s: OVN northbound DB management utility\n\
323 usage: %s [OPTIONS] COMMAND [ARG...]\n\
324 \n\
325 General commands:\n\
326   init                      initialize the database\n\
327   show                      print overview of database contents\n\
328   show SWITCH               print overview of database contents for SWITCH\n\
329   show ROUTER               print overview of database contents for ROUTER\n\
330 \n\
331 Logical switch commands:\n\
332   ls-add [SWITCH]           create a logical switch named SWITCH\n\
333   ls-del SWITCH             delete SWITCH and all its ports\n\
334   ls-list                   print the names of all logical switches\n\
335 \n\
336 ACL commands:\n\
337   acl-add SWITCH DIRECTION PRIORITY MATCH ACTION [log]\n\
338                             add an ACL to SWITCH\n\
339   acl-del SWITCH [DIRECTION [PRIORITY MATCH]]\n\
340                             remove ACLs from SWITCH\n\
341   acl-list SWITCH           print ACLs for SWITCH\n\
342 \n\
343 Logical switch port commands:\n\
344   lsp-add SWITCH PORT       add logical port PORT on SWITCH\n\
345   lsp-add SWITCH PORT PARENT TAG\n\
346                             add logical port PORT on SWITCH with PARENT\n\
347                             on TAG\n\
348   lsp-del PORT              delete PORT from its attached switch\n\
349   lsp-list SWITCH           print the names of all logical ports on SWITCH\n\
350   lsp-get-parent PORT       get the parent of PORT if set\n\
351   lsp-get-tag PORT          get the PORT's tag if set\n\
352   lsp-set-addresses PORT [ADDRESS]...\n\
353                             set MAC or MAC+IP addresses for PORT.\n\
354   lsp-get-addresses PORT    get a list of MAC addresses on PORT\n\
355   lsp-set-port-security PORT [ADDRS]...\n\
356                             set port security addresses for PORT.\n\
357   lsp-get-port-security PORT    get PORT's port security addresses\n\
358   lsp-get-up PORT           get state of PORT ('up' or 'down')\n\
359   lsp-set-enabled PORT STATE\n\
360                             set administrative state PORT\n\
361                             ('enabled' or 'disabled')\n\
362   lsp-get-enabled PORT      get administrative state PORT\n\
363                             ('enabled' or 'disabled')\n\
364   lsp-set-type PORT TYPE    set the type for PORT\n\
365   lsp-get-type PORT         get the type for PORT\n\
366   lsp-set-options PORT KEY=VALUE [KEY=VALUE]...\n\
367                             set options related to the type of PORT\n\
368   lsp-get-options PORT      get the type specific options for PORT\n\
369   lsp-set-dhcpv4-options PORT [DHCP_OPTIONS_UUID]\n\
370                             set dhcpv4 options for PORT\n\
371   lsp-get-dhcpv4-options PORT  get the dhcpv4 options for PORT\n\
372 \n\
373 Logical router commands:\n\
374   lr-add [ROUTER]           create a logical router named ROUTER\n\
375   lr-del ROUTER             delete ROUTER and all its ports\n\
376   lr-list                   print the names of all logical routers\n\
377 \n\
378 Logical router port commands:\n\
379   lrp-add ROUTER PORT MAC NETWORK... [peer=PEER]\n\
380                             add logical port PORT on ROUTER\n\
381   lrp-del PORT              delete PORT from its attached router\n\
382   lrp-list ROUTER           print the names of all ports on ROUTER\n\
383   lrp-set-enabled PORT STATE\n\
384                             set administrative state PORT\n\
385                             ('enabled' or 'disabled')\n\
386   lrp-get-enabled PORT      get administrative state PORT\n\
387                             ('enabled' or 'disabled')\n\
388 \n\
389 Route commands:\n\
390   lr-route-add ROUTER PREFIX NEXTHOP [PORT]\n\
391                             add a route to ROUTER\n\
392   lr-route-del ROUTER [PREFIX]\n\
393                             remove routes from ROUTER\n\
394   lr-route-list ROUTER      print routes for ROUTER\n\
395 \n\
396 \n\
397 DHCP Options commands:\n\
398   dhcp-options-create CIDR [EXTERNAL_IDS]\n\
399                            create a DHCP options row with CIDR\n\
400   dhcp-options-del DHCP_OPTIONS_UUID\n\
401                            delete DHCP_OPTIONS_UUID\n\
402   dhcp-options-list        \n\
403                            lists the DHCP_Options rows\n\
404   dhcp-options-set-options DHCP_OPTIONS_UUID  KEY=VALUE [KEY=VALUE]...\n\
405                            set DHCP options to the DHCP_OPTIONS_UUID\n\
406   dhcp-options-get-options DHCO_OPTIONS_UUID \n\
407                            displays the DHCP options of th DHCP_OPTIONS_UUID\n\
408 \n\
409 %s\
410 \n\
411 Options:\n\
412   --db=DATABASE               connect to DATABASE\n\
413                               (default: %s)\n\
414   --no-wait, --wait=none      do not wait for OVN reconfiguration (default)\n\
415   --wait=sb                   wait for southbound database update\n\
416   --wait=hv                   wait for all chassis to catch up\n\
417   -t, --timeout=SECS          wait at most SECS seconds\n\
418   --dry-run                   do not commit changes to database\n\
419   --oneline                   print exactly one line of output per command\n",
420            program_name, program_name, ctl_get_db_cmd_usage(), nbctl_default_db());
421     vlog_usage();
422     printf("\
423   --no-syslog             equivalent to --verbose=nbctl:syslog:warn\n");
424     printf("\n\
425 Other options:\n\
426   -h, --help                  display this help message\n\
427   -V, --version               display version information\n");
428     exit(EXIT_SUCCESS);
429 }
430 \f
431
432 /* Find a logical router given its id. */
433 static const struct nbrec_logical_router *
434 lr_by_name_or_uuid(struct ctl_context *ctx, const char *id,
435                         bool must_exist)
436 {
437     const struct nbrec_logical_router *lr = NULL;
438     bool is_uuid = false;
439     struct uuid lr_uuid;
440
441     if (uuid_from_string(&lr_uuid, id)) {
442         is_uuid = true;
443         lr = nbrec_logical_router_get_for_uuid(ctx->idl, &lr_uuid);
444     }
445
446     if (!lr) {
447         const struct nbrec_logical_router *iter;
448
449         NBREC_LOGICAL_ROUTER_FOR_EACH(iter, ctx->idl) {
450             if (strcmp(iter->name, id)) {
451                 continue;
452             }
453             if (lr) {
454                 ctl_fatal("Multiple logical routers named '%s'.  "
455                           "Use a UUID.", id);
456             }
457             lr = iter;
458         }
459     }
460
461     if (!lr && must_exist) {
462         ctl_fatal("%s: router %s not found", id, is_uuid ? "UUID" : "name");
463     }
464
465     return lr;
466 }
467
468 static const struct nbrec_logical_switch *
469 ls_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist)
470 {
471     const struct nbrec_logical_switch *ls = NULL;
472
473     struct uuid ls_uuid;
474     bool is_uuid = uuid_from_string(&ls_uuid, id);
475     if (is_uuid) {
476         ls = nbrec_logical_switch_get_for_uuid(ctx->idl, &ls_uuid);
477     }
478
479     if (!ls) {
480         const struct nbrec_logical_switch *iter;
481
482         NBREC_LOGICAL_SWITCH_FOR_EACH(iter, ctx->idl) {
483             if (strcmp(iter->name, id)) {
484                 continue;
485             }
486             if (ls) {
487                 ctl_fatal("Multiple logical switches named '%s'.  "
488                           "Use a UUID.", id);
489             }
490             ls = iter;
491         }
492     }
493
494     if (!ls && must_exist) {
495         ctl_fatal("%s: switch %s not found", id, is_uuid ? "UUID" : "name");
496     }
497
498     return ls;
499 }
500
501 /* Given pointer to logical router, this routine prints the router
502  * information.  */
503 static void
504 print_lr(const struct nbrec_logical_router *lr, struct ds *s)
505 {
506     ds_put_format(s, "    router "UUID_FMT" (%s)\n",
507                   UUID_ARGS(&lr->header_.uuid), lr->name);
508
509     for (size_t i = 0; i < lr->n_ports; i++) {
510         const struct nbrec_logical_router_port *lrp = lr->ports[i];
511         ds_put_format(s, "        port %s\n", lrp->name);
512         if (lrp->mac) {
513             ds_put_cstr(s, "            mac: ");
514             ds_put_format(s, "\"%s\"\n", lrp->mac);
515         }
516         if (lrp->n_networks) {
517             ds_put_cstr(s, "            networks: [");
518             for (size_t j = 0; j < lrp->n_networks; j++) {
519                 ds_put_format(s, "%s\"%s\"",
520                         j == 0 ? "" : ", ",
521                         lrp->networks[j]);
522             }
523             ds_put_cstr(s, "]\n");
524         }
525     }
526 }
527
528 static void
529 print_ls(const struct nbrec_logical_switch *ls, struct ds *s)
530 {
531     ds_put_format(s, "    switch "UUID_FMT" (%s)\n",
532                   UUID_ARGS(&ls->header_.uuid), ls->name);
533
534     for (size_t i = 0; i < ls->n_ports; i++) {
535         const struct nbrec_logical_switch_port *lsp = ls->ports[i];
536
537         ds_put_format(s, "        port %s\n", lsp->name);
538         if (lsp->parent_name) {
539             ds_put_format(s, "            parent: %s\n", lsp->parent_name);
540         }
541         if (lsp->n_tag) {
542             ds_put_format(s, "            tag: %"PRIu64"\n", lsp->tag[0]);
543         }
544         if (lsp->n_addresses) {
545             ds_put_cstr(s, "            addresses: [");
546             for (size_t j = 0; j < lsp->n_addresses; j++) {
547                 ds_put_format(s, "%s\"%s\"",
548                         j == 0 ? "" : ", ",
549                         lsp->addresses[j]);
550             }
551             ds_put_cstr(s, "]\n");
552         }
553     }
554 }
555
556 static void
557 nbctl_init(struct ctl_context *ctx OVS_UNUSED)
558 {
559 }
560
561 static void
562 nbctl_show(struct ctl_context *ctx)
563 {
564     const struct nbrec_logical_switch *ls;
565
566     if (ctx->argc == 2) {
567         ls = ls_by_name_or_uuid(ctx, ctx->argv[1], false);
568         if (ls) {
569             print_ls(ls, &ctx->output);
570         }
571     } else {
572         NBREC_LOGICAL_SWITCH_FOR_EACH(ls, ctx->idl) {
573             print_ls(ls, &ctx->output);
574         }
575     }
576     const struct nbrec_logical_router *lr;
577
578     if (ctx->argc == 2) {
579         lr = lr_by_name_or_uuid(ctx, ctx->argv[1], false);
580         if (lr) {
581             print_lr(lr, &ctx->output);
582         }
583     } else {
584         NBREC_LOGICAL_ROUTER_FOR_EACH(lr, ctx->idl) {
585             print_lr(lr, &ctx->output);
586         }
587     }
588 }
589
590 static void
591 nbctl_ls_add(struct ctl_context *ctx)
592 {
593     const char *ls_name = ctx->argc == 2 ? ctx->argv[1] : NULL;
594
595     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
596     bool add_duplicate = shash_find(&ctx->options, "--add-duplicate") != NULL;
597     if (may_exist && add_duplicate) {
598         ctl_fatal("--may-exist and --add-duplicate may not be used together");
599     }
600
601     if (ls_name) {
602         if (!add_duplicate) {
603             const struct nbrec_logical_switch *ls;
604             NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->idl) {
605                 if (!strcmp(ls->name, ls_name)) {
606                     if (may_exist) {
607                         return;
608                     }
609                     ctl_fatal("%s: a switch with this name already exists",
610                               ls_name);
611                 }
612             }
613         }
614     } else if (may_exist) {
615         ctl_fatal("--may-exist requires specifying a name");
616     } else if (add_duplicate) {
617         ctl_fatal("--add-duplicate requires specifying a name");
618     }
619
620     struct nbrec_logical_switch *ls;
621     ls = nbrec_logical_switch_insert(ctx->txn);
622     if (ls_name) {
623         nbrec_logical_switch_set_name(ls, ls_name);
624     }
625 }
626
627 static void
628 nbctl_ls_del(struct ctl_context *ctx)
629 {
630     bool must_exist = !shash_find(&ctx->options, "--if-exists");
631     const char *id = ctx->argv[1];
632     const struct nbrec_logical_switch *ls;
633
634     ls = ls_by_name_or_uuid(ctx, id, must_exist);
635     if (!ls) {
636         return;
637     }
638
639     nbrec_logical_switch_delete(ls);
640 }
641
642 static void
643 nbctl_ls_list(struct ctl_context *ctx)
644 {
645     const struct nbrec_logical_switch *ls;
646     struct smap lswitches;
647
648     smap_init(&lswitches);
649     NBREC_LOGICAL_SWITCH_FOR_EACH(ls, ctx->idl) {
650         smap_add_format(&lswitches, ls->name, UUID_FMT " (%s)",
651                         UUID_ARGS(&ls->header_.uuid), ls->name);
652     }
653     const struct smap_node **nodes = smap_sort(&lswitches);
654     for (size_t i = 0; i < smap_count(&lswitches); i++) {
655         const struct smap_node *node = nodes[i];
656         ds_put_format(&ctx->output, "%s\n", node->value);
657     }
658     smap_destroy(&lswitches);
659     free(nodes);
660 }
661 \f
662 static const struct nbrec_logical_switch_port *
663 lsp_by_name_or_uuid(struct ctl_context *ctx, const char *id,
664                     bool must_exist)
665 {
666     const struct nbrec_logical_switch_port *lsp = NULL;
667
668     struct uuid lsp_uuid;
669     bool is_uuid = uuid_from_string(&lsp_uuid, id);
670     if (is_uuid) {
671         lsp = nbrec_logical_switch_port_get_for_uuid(ctx->idl, &lsp_uuid);
672     }
673
674     if (!lsp) {
675         NBREC_LOGICAL_SWITCH_PORT_FOR_EACH(lsp, ctx->idl) {
676             if (!strcmp(lsp->name, id)) {
677                 break;
678             }
679         }
680     }
681
682     if (!lsp && must_exist) {
683         ctl_fatal("%s: port %s not found", id, is_uuid ? "UUID" : "name");
684     }
685
686     return lsp;
687 }
688
689 /* Returns the logical switch that contains 'lsp'. */
690 static const struct nbrec_logical_switch *
691 lsp_to_ls(const struct ovsdb_idl *idl,
692                const struct nbrec_logical_switch_port *lsp)
693 {
694     const struct nbrec_logical_switch *ls;
695     NBREC_LOGICAL_SWITCH_FOR_EACH (ls, idl) {
696         for (size_t i = 0; i < ls->n_ports; i++) {
697             if (ls->ports[i] == lsp) {
698                 return ls;
699             }
700         }
701     }
702
703     /* Can't happen because of the database schema */
704     ctl_fatal("logical port %s is not part of any logical switch",
705               lsp->name);
706 }
707
708 static const char *
709 ls_get_name(const struct nbrec_logical_switch *ls,
710                  char uuid_s[UUID_LEN + 1], size_t uuid_s_size)
711 {
712     if (ls->name[0]) {
713         return ls->name;
714     }
715     snprintf(uuid_s, uuid_s_size, UUID_FMT, UUID_ARGS(&ls->header_.uuid));
716     return uuid_s;
717 }
718
719 static void
720 nbctl_lsp_add(struct ctl_context *ctx)
721 {
722     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
723
724     const struct nbrec_logical_switch *ls;
725     ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
726
727     const char *parent_name;
728     int64_t tag;
729     if (ctx->argc == 3) {
730         parent_name = NULL;
731         tag = -1;
732     } else if (ctx->argc == 5) {
733         /* Validate tag. */
734         parent_name = ctx->argv[3];
735         if (!ovs_scan(ctx->argv[4], "%"SCNd64, &tag)
736             || tag < 0 || tag > 4095) {
737             ctl_fatal("%s: invalid tag", ctx->argv[4]);
738         }
739     } else {
740         ctl_fatal("lsp-add with parent must also specify a tag");
741     }
742
743     const char *lsp_name = ctx->argv[2];
744     const struct nbrec_logical_switch_port *lsp;
745     lsp = lsp_by_name_or_uuid(ctx, lsp_name, false);
746     if (lsp) {
747         if (!may_exist) {
748             ctl_fatal("%s: a port with this name already exists",
749                       lsp_name);
750         }
751
752         const struct nbrec_logical_switch *lsw;
753         lsw = lsp_to_ls(ctx->idl, lsp);
754         if (lsw != ls) {
755             char uuid_s[UUID_LEN + 1];
756             ctl_fatal("%s: port already exists but in switch %s", lsp_name,
757                       ls_get_name(lsw, uuid_s, sizeof uuid_s));
758         }
759
760         if (parent_name) {
761             if (!lsp->parent_name) {
762                 ctl_fatal("%s: port already exists but has no parent",
763                           lsp_name);
764             } else if (strcmp(parent_name, lsp->parent_name)) {
765                 ctl_fatal("%s: port already exists with different parent %s",
766                           lsp_name, lsp->parent_name);
767             }
768
769             if (!lsp->n_tag) {
770                 ctl_fatal("%s: port already exists but has no tag",
771                           lsp_name);
772             } else if (lsp->tag[0] != tag) {
773                 ctl_fatal("%s: port already exists with different "
774                           "tag %"PRId64, lsp_name, lsp->tag[0]);
775             }
776         } else {
777             if (lsp->parent_name) {
778                 ctl_fatal("%s: port already exists but has parent %s",
779                           lsp_name, lsp->parent_name);
780             }
781         }
782
783         return;
784     }
785
786     /* Create the logical port. */
787     lsp = nbrec_logical_switch_port_insert(ctx->txn);
788     nbrec_logical_switch_port_set_name(lsp, lsp_name);
789     if (tag >= 0) {
790         nbrec_logical_switch_port_set_parent_name(lsp, parent_name);
791         nbrec_logical_switch_port_set_tag(lsp, &tag, 1);
792     }
793
794     /* Insert the logical port into the logical switch. */
795     nbrec_logical_switch_verify_ports(ls);
796     struct nbrec_logical_switch_port **new_ports = xmalloc(sizeof *new_ports *
797                                                     (ls->n_ports + 1));
798     memcpy(new_ports, ls->ports, sizeof *new_ports * ls->n_ports);
799     new_ports[ls->n_ports] = CONST_CAST(struct nbrec_logical_switch_port *,
800                                              lsp);
801     nbrec_logical_switch_set_ports(ls, new_ports, ls->n_ports + 1);
802     free(new_ports);
803 }
804
805 /* Removes logical switch port 'ls->ports[idx]'. */
806 static void
807 remove_lsp(const struct nbrec_logical_switch *ls, size_t idx)
808 {
809     const struct nbrec_logical_switch_port *lsp = ls->ports[idx];
810
811     /* First remove 'lsp' from the array of ports.  This is what will
812      * actually cause the logical port to be deleted when the transaction is
813      * sent to the database server (due to garbage collection). */
814     struct nbrec_logical_switch_port **new_ports
815         = xmemdup(ls->ports, sizeof *new_ports * ls->n_ports);
816     new_ports[idx] = new_ports[ls->n_ports - 1];
817     nbrec_logical_switch_verify_ports(ls);
818     nbrec_logical_switch_set_ports(ls, new_ports, ls->n_ports - 1);
819     free(new_ports);
820
821     /* Delete 'lsp' from the IDL.  This won't have a real effect on the
822      * database server (the IDL will suppress it in fact) but it means that it
823      * won't show up when we iterate with NBREC_LOGICAL_SWITCH_PORT_FOR_EACH
824      * later. */
825     nbrec_logical_switch_port_delete(lsp);
826 }
827
828 static void
829 nbctl_lsp_del(struct ctl_context *ctx)
830 {
831     bool must_exist = !shash_find(&ctx->options, "--if-exists");
832     const struct nbrec_logical_switch_port *lsp;
833
834     lsp = lsp_by_name_or_uuid(ctx, ctx->argv[1], must_exist);
835     if (!lsp) {
836         return;
837     }
838
839     /* Find the switch that contains 'lsp', then delete it. */
840     const struct nbrec_logical_switch *ls;
841     NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->idl) {
842         for (size_t i = 0; i < ls->n_ports; i++) {
843             if (ls->ports[i] == lsp) {
844                 remove_lsp(ls, i);
845                 return;
846             }
847         }
848     }
849
850     /* Can't happen because of the database schema. */
851     ctl_fatal("logical port %s is not part of any logical switch",
852               ctx->argv[1]);
853 }
854
855 static void
856 nbctl_lsp_list(struct ctl_context *ctx)
857 {
858     const char *id = ctx->argv[1];
859     const struct nbrec_logical_switch *ls;
860     struct smap lsps;
861     size_t i;
862
863     ls = ls_by_name_or_uuid(ctx, id, true);
864
865     smap_init(&lsps);
866     for (i = 0; i < ls->n_ports; i++) {
867         const struct nbrec_logical_switch_port *lsp = ls->ports[i];
868         smap_add_format(&lsps, lsp->name, UUID_FMT " (%s)",
869                         UUID_ARGS(&lsp->header_.uuid), lsp->name);
870     }
871     const struct smap_node **nodes = smap_sort(&lsps);
872     for (i = 0; i < smap_count(&lsps); i++) {
873         const struct smap_node *node = nodes[i];
874         ds_put_format(&ctx->output, "%s\n", node->value);
875     }
876     smap_destroy(&lsps);
877     free(nodes);
878 }
879
880 static void
881 nbctl_lsp_get_parent(struct ctl_context *ctx)
882 {
883     const struct nbrec_logical_switch_port *lsp;
884
885     lsp = lsp_by_name_or_uuid(ctx, ctx->argv[1], true);
886     if (lsp->parent_name) {
887         ds_put_format(&ctx->output, "%s\n", lsp->parent_name);
888     }
889 }
890
891 static void
892 nbctl_lsp_get_tag(struct ctl_context *ctx)
893 {
894     const struct nbrec_logical_switch_port *lsp;
895
896     lsp = lsp_by_name_or_uuid(ctx, ctx->argv[1], true);
897     if (lsp->n_tag > 0) {
898         ds_put_format(&ctx->output, "%"PRId64"\n", lsp->tag[0]);
899     }
900 }
901
902 static void
903 nbctl_lsp_set_addresses(struct ctl_context *ctx)
904 {
905     const char *id = ctx->argv[1];
906     const struct nbrec_logical_switch_port *lsp;
907
908     lsp = lsp_by_name_or_uuid(ctx, id, true);
909
910     int i;
911     for (i = 2; i < ctx->argc; i++) {
912         struct eth_addr ea;
913
914         if (strcmp(ctx->argv[i], "unknown")
915             && !ovs_scan(ctx->argv[i], ETH_ADDR_SCAN_FMT,
916                          ETH_ADDR_SCAN_ARGS(ea))) {
917             ctl_fatal("%s: Invalid address format. See ovn-nb(5). "
918                       "Hint: An Ethernet address must be "
919                       "listed before an IP address, together as a single "
920                       "argument.", ctx->argv[i]);
921         }
922     }
923
924     nbrec_logical_switch_port_set_addresses(lsp,
925             (const char **) ctx->argv + 2, ctx->argc - 2);
926 }
927
928 static void
929 nbctl_lsp_get_addresses(struct ctl_context *ctx)
930 {
931     const char *id = ctx->argv[1];
932     const struct nbrec_logical_switch_port *lsp;
933     struct svec addresses;
934     const char *mac;
935     size_t i;
936
937     lsp = lsp_by_name_or_uuid(ctx, id, true);
938
939     svec_init(&addresses);
940     for (i = 0; i < lsp->n_addresses; i++) {
941         svec_add(&addresses, lsp->addresses[i]);
942     }
943     svec_sort(&addresses);
944     SVEC_FOR_EACH(i, mac, &addresses) {
945         ds_put_format(&ctx->output, "%s\n", mac);
946     }
947     svec_destroy(&addresses);
948 }
949
950 static void
951 nbctl_lsp_set_port_security(struct ctl_context *ctx)
952 {
953     const char *id = ctx->argv[1];
954     const struct nbrec_logical_switch_port *lsp;
955
956     lsp = lsp_by_name_or_uuid(ctx, id, true);
957     nbrec_logical_switch_port_set_port_security(lsp,
958             (const char **) ctx->argv + 2, ctx->argc - 2);
959 }
960
961 static void
962 nbctl_lsp_get_port_security(struct ctl_context *ctx)
963 {
964     const char *id = ctx->argv[1];
965     const struct nbrec_logical_switch_port *lsp;
966     struct svec addrs;
967     const char *addr;
968     size_t i;
969
970     lsp = lsp_by_name_or_uuid(ctx, id, true);
971     svec_init(&addrs);
972     for (i = 0; i < lsp->n_port_security; i++) {
973         svec_add(&addrs, lsp->port_security[i]);
974     }
975     svec_sort(&addrs);
976     SVEC_FOR_EACH(i, addr, &addrs) {
977         ds_put_format(&ctx->output, "%s\n", addr);
978     }
979     svec_destroy(&addrs);
980 }
981
982 static void
983 nbctl_lsp_get_up(struct ctl_context *ctx)
984 {
985     const char *id = ctx->argv[1];
986     const struct nbrec_logical_switch_port *lsp;
987
988     lsp = lsp_by_name_or_uuid(ctx, id, true);
989     ds_put_format(&ctx->output,
990                   "%s\n", (lsp->up && *lsp->up) ? "up" : "down");
991 }
992
993 static bool
994 parse_enabled(const char *state)
995 {
996     if (!strcasecmp(state, "enabled")) {
997         return true;
998     } else if (!strcasecmp(state, "disabled")) {
999         return false;
1000     } else {
1001         ctl_fatal("%s: state must be \"enabled\" or \"disabled\"", state);
1002     }
1003 }
1004
1005 static void
1006 nbctl_lsp_set_enabled(struct ctl_context *ctx)
1007 {
1008     const char *id = ctx->argv[1];
1009     const char *state = ctx->argv[2];
1010     const struct nbrec_logical_switch_port *lsp;
1011
1012     lsp = lsp_by_name_or_uuid(ctx, id, true);
1013     bool enabled = parse_enabled(state);
1014     nbrec_logical_switch_port_set_enabled(lsp, &enabled, 1);
1015 }
1016
1017 static void
1018 nbctl_lsp_get_enabled(struct ctl_context *ctx)
1019 {
1020     const char *id = ctx->argv[1];
1021     const struct nbrec_logical_switch_port *lsp;
1022
1023     lsp = lsp_by_name_or_uuid(ctx, id, true);
1024     ds_put_format(&ctx->output, "%s\n",
1025                   !lsp->enabled || *lsp->enabled ? "enabled" : "disabled");
1026 }
1027
1028 static void
1029 nbctl_lsp_set_type(struct ctl_context *ctx)
1030 {
1031     const char *id = ctx->argv[1];
1032     const char *type = ctx->argv[2];
1033     const struct nbrec_logical_switch_port *lsp;
1034
1035     lsp = lsp_by_name_or_uuid(ctx, id, true);
1036     nbrec_logical_switch_port_set_type(lsp, type);
1037 }
1038
1039 static void
1040 nbctl_lsp_get_type(struct ctl_context *ctx)
1041 {
1042     const char *id = ctx->argv[1];
1043     const struct nbrec_logical_switch_port *lsp;
1044
1045     lsp = lsp_by_name_or_uuid(ctx, id, true);
1046     ds_put_format(&ctx->output, "%s\n", lsp->type);
1047 }
1048
1049 static void
1050 nbctl_lsp_set_options(struct ctl_context *ctx)
1051 {
1052     const char *id = ctx->argv[1];
1053     const struct nbrec_logical_switch_port *lsp;
1054     size_t i;
1055     struct smap options = SMAP_INITIALIZER(&options);
1056
1057     lsp = lsp_by_name_or_uuid(ctx, id, true);
1058     for (i = 2; i < ctx->argc; i++) {
1059         char *key, *value;
1060         value = xstrdup(ctx->argv[i]);
1061         key = strsep(&value, "=");
1062         if (value) {
1063             smap_add(&options, key, value);
1064         }
1065         free(key);
1066     }
1067
1068     nbrec_logical_switch_port_set_options(lsp, &options);
1069
1070     smap_destroy(&options);
1071 }
1072
1073 static void
1074 nbctl_lsp_get_options(struct ctl_context *ctx)
1075 {
1076     const char *id = ctx->argv[1];
1077     const struct nbrec_logical_switch_port *lsp;
1078     struct smap_node *node;
1079
1080     lsp = lsp_by_name_or_uuid(ctx, id, true);
1081     SMAP_FOR_EACH(node, &lsp->options) {
1082         ds_put_format(&ctx->output, "%s=%s\n", node->key, node->value);
1083     }
1084 }
1085
1086 static void
1087 nbctl_lsp_set_dhcpv4_options(struct ctl_context *ctx)
1088 {
1089     const char *id = ctx->argv[1];
1090     const struct nbrec_logical_switch_port *lsp;
1091
1092     lsp = lsp_by_name_or_uuid(ctx, id, true);
1093     const struct nbrec_dhcp_options *dhcp_opt = NULL;
1094     if (ctx->argc == 3 ) {
1095         dhcp_opt = dhcp_options_get(ctx, ctx->argv[2], true);
1096     }
1097
1098     if (dhcp_opt) {
1099         ovs_be32 ip;
1100         unsigned int plen;
1101         char *error = ip_parse_cidr(dhcp_opt->cidr, &ip, &plen);
1102         if (error){
1103             free(error);
1104             ctl_fatal("DHCP options cidr '%s' is not IPv4", dhcp_opt->cidr);
1105             return;
1106         }
1107     }
1108     nbrec_logical_switch_port_set_dhcpv4_options(lsp, dhcp_opt);
1109 }
1110
1111 static void
1112 nbctl_lsp_get_dhcpv4_options(struct ctl_context *ctx)
1113 {
1114     const char *id = ctx->argv[1];
1115     const struct nbrec_logical_switch_port *lsp;
1116
1117     lsp = lsp_by_name_or_uuid(ctx, id, true);
1118     if (lsp->dhcpv4_options) {
1119         ds_put_format(&ctx->output, UUID_FMT " (%s)\n",
1120                       UUID_ARGS(&lsp->dhcpv4_options->header_.uuid),
1121                       lsp->dhcpv4_options->cidr);
1122     }
1123 }
1124
1125 enum {
1126     DIR_FROM_LPORT,
1127     DIR_TO_LPORT
1128 };
1129
1130 static int
1131 dir_encode(const char *dir)
1132 {
1133     if (!strcmp(dir, "from-lport")) {
1134         return DIR_FROM_LPORT;
1135     } else if (!strcmp(dir, "to-lport")) {
1136         return DIR_TO_LPORT;
1137     }
1138
1139     OVS_NOT_REACHED();
1140 }
1141
1142 static int
1143 acl_cmp(const void *acl1_, const void *acl2_)
1144 {
1145     const struct nbrec_acl *const *acl1p = acl1_;
1146     const struct nbrec_acl *const *acl2p = acl2_;
1147     const struct nbrec_acl *acl1 = *acl1p;
1148     const struct nbrec_acl *acl2 = *acl2p;
1149
1150     int dir1 = dir_encode(acl1->direction);
1151     int dir2 = dir_encode(acl2->direction);
1152
1153     if (dir1 != dir2) {
1154         return dir1 < dir2 ? -1 : 1;
1155     } else if (acl1->priority != acl2->priority) {
1156         return acl1->priority > acl2->priority ? -1 : 1;
1157     } else {
1158         return strcmp(acl1->match, acl2->match);
1159     }
1160 }
1161
1162 static void
1163 nbctl_acl_list(struct ctl_context *ctx)
1164 {
1165     const struct nbrec_logical_switch *ls;
1166     const struct nbrec_acl **acls;
1167     size_t i;
1168
1169     ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
1170
1171     acls = xmalloc(sizeof *acls * ls->n_acls);
1172     for (i = 0; i < ls->n_acls; i++) {
1173         acls[i] = ls->acls[i];
1174     }
1175
1176     qsort(acls, ls->n_acls, sizeof *acls, acl_cmp);
1177
1178     for (i = 0; i < ls->n_acls; i++) {
1179         const struct nbrec_acl *acl = acls[i];
1180         ds_put_format(&ctx->output, "%10s %5"PRId64" (%s) %s%s\n",
1181                       acl->direction, acl->priority,
1182                       acl->match, acl->action, acl->log ? " log" : "");
1183     }
1184
1185     free(acls);
1186 }
1187
1188 static const char *
1189 parse_direction(const char *arg)
1190 {
1191     /* Validate direction.  Only require the first letter. */
1192     if (arg[0] == 't') {
1193         return "to-lport";
1194     } else if (arg[0] == 'f') {
1195         return "from-lport";
1196     } else {
1197         ctl_fatal("%s: direction must be \"to-lport\" or \"from-lport\"", arg);
1198     }
1199 }
1200
1201 static int
1202 parse_priority(const char *arg)
1203 {
1204     /* Validate priority. */
1205     int64_t priority;
1206     if (!ovs_scan(arg, "%"SCNd64, &priority)
1207         || priority < 0 || priority > 32767) {
1208         ctl_fatal("%s: priority must in range 0...32767", arg);
1209     }
1210     return priority;
1211 }
1212
1213 static void
1214 nbctl_acl_add(struct ctl_context *ctx)
1215 {
1216     const struct nbrec_logical_switch *ls;
1217     const char *action = ctx->argv[5];
1218
1219     ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
1220
1221     const char *direction = parse_direction(ctx->argv[2]);
1222     int64_t priority = parse_priority(ctx->argv[3]);
1223
1224     /* Validate action. */
1225     if (strcmp(action, "allow") && strcmp(action, "allow-related")
1226         && strcmp(action, "drop") && strcmp(action, "reject")) {
1227         ctl_fatal("%s: action must be one of \"allow\", \"allow-related\", "
1228                   "\"drop\", and \"reject\"", action);
1229         return;
1230     }
1231
1232     /* Create the acl. */
1233     struct nbrec_acl *acl = nbrec_acl_insert(ctx->txn);
1234     nbrec_acl_set_priority(acl, priority);
1235     nbrec_acl_set_direction(acl, direction);
1236     nbrec_acl_set_match(acl, ctx->argv[4]);
1237     nbrec_acl_set_action(acl, action);
1238     if (shash_find(&ctx->options, "--log") != NULL) {
1239         nbrec_acl_set_log(acl, true);
1240     }
1241
1242     /* Insert the acl into the logical switch. */
1243     nbrec_logical_switch_verify_acls(ls);
1244     struct nbrec_acl **new_acls = xmalloc(sizeof *new_acls * (ls->n_acls + 1));
1245     memcpy(new_acls, ls->acls, sizeof *new_acls * ls->n_acls);
1246     new_acls[ls->n_acls] = acl;
1247     nbrec_logical_switch_set_acls(ls, new_acls, ls->n_acls + 1);
1248     free(new_acls);
1249 }
1250
1251 static void
1252 nbctl_acl_del(struct ctl_context *ctx)
1253 {
1254     const struct nbrec_logical_switch *ls;
1255     ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
1256
1257     if (ctx->argc != 2 && ctx->argc != 3 && ctx->argc != 5) {
1258         ctl_fatal("cannot specify priority without match");
1259     }
1260
1261     if (ctx->argc == 2) {
1262         /* If direction, priority, and match are not specified, delete
1263          * all ACLs. */
1264         nbrec_logical_switch_verify_acls(ls);
1265         nbrec_logical_switch_set_acls(ls, NULL, 0);
1266         return;
1267     }
1268
1269     const char *direction = parse_direction(ctx->argv[2]);
1270
1271     /* If priority and match are not specified, delete all ACLs with the
1272      * specified direction. */
1273     if (ctx->argc == 3) {
1274         struct nbrec_acl **new_acls = xmalloc(sizeof *new_acls * ls->n_acls);
1275
1276         int n_acls = 0;
1277         for (size_t i = 0; i < ls->n_acls; i++) {
1278             if (strcmp(direction, ls->acls[i]->direction)) {
1279                 new_acls[n_acls++] = ls->acls[i];
1280             }
1281         }
1282
1283         nbrec_logical_switch_verify_acls(ls);
1284         nbrec_logical_switch_set_acls(ls, new_acls, n_acls);
1285         free(new_acls);
1286         return;
1287     }
1288
1289     int64_t priority = parse_priority(ctx->argv[3]);
1290
1291     /* Remove the matching rule. */
1292     for (size_t i = 0; i < ls->n_acls; i++) {
1293         struct nbrec_acl *acl = ls->acls[i];
1294
1295         if (priority == acl->priority && !strcmp(ctx->argv[4], acl->match) &&
1296              !strcmp(direction, acl->direction)) {
1297             struct nbrec_acl **new_acls
1298                 = xmemdup(ls->acls, sizeof *new_acls * ls->n_acls);
1299             new_acls[i] = ls->acls[ls->n_acls - 1];
1300             nbrec_logical_switch_verify_acls(ls);
1301             nbrec_logical_switch_set_acls(ls, new_acls,
1302                                           ls->n_acls - 1);
1303             free(new_acls);
1304             return;
1305         }
1306     }
1307 }
1308 \f
1309 static void
1310 nbctl_lr_add(struct ctl_context *ctx)
1311 {
1312     const char *lr_name = ctx->argc == 2 ? ctx->argv[1] : NULL;
1313
1314     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1315     bool add_duplicate = shash_find(&ctx->options, "--add-duplicate") != NULL;
1316     if (may_exist && add_duplicate) {
1317         ctl_fatal("--may-exist and --add-duplicate may not be used together");
1318     }
1319
1320     if (lr_name) {
1321         if (!add_duplicate) {
1322             const struct nbrec_logical_router *lr;
1323             NBREC_LOGICAL_ROUTER_FOR_EACH (lr, ctx->idl) {
1324                 if (!strcmp(lr->name, lr_name)) {
1325                     if (may_exist) {
1326                         return;
1327                     }
1328                     ctl_fatal("%s: a router with this name already exists",
1329                               lr_name);
1330                 }
1331             }
1332         }
1333     } else if (may_exist) {
1334         ctl_fatal("--may-exist requires specifying a name");
1335     } else if (add_duplicate) {
1336         ctl_fatal("--add-duplicate requires specifying a name");
1337     }
1338
1339     struct nbrec_logical_router *lr;
1340     lr = nbrec_logical_router_insert(ctx->txn);
1341     if (lr_name) {
1342         nbrec_logical_router_set_name(lr, lr_name);
1343     }
1344 }
1345
1346 static void
1347 nbctl_lr_del(struct ctl_context *ctx)
1348 {
1349     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1350     const char *id = ctx->argv[1];
1351     const struct nbrec_logical_router *lr;
1352
1353     lr = lr_by_name_or_uuid(ctx, id, must_exist);
1354     if (!lr) {
1355         return;
1356     }
1357
1358     nbrec_logical_router_delete(lr);
1359 }
1360
1361 static void
1362 nbctl_lr_list(struct ctl_context *ctx)
1363 {
1364     const struct nbrec_logical_router *lr;
1365     struct smap lrs;
1366
1367     smap_init(&lrs);
1368     NBREC_LOGICAL_ROUTER_FOR_EACH(lr, ctx->idl) {
1369         smap_add_format(&lrs, lr->name, UUID_FMT " (%s)",
1370                         UUID_ARGS(&lr->header_.uuid), lr->name);
1371     }
1372     const struct smap_node **nodes = smap_sort(&lrs);
1373     for (size_t i = 0; i < smap_count(&lrs); i++) {
1374         const struct smap_node *node = nodes[i];
1375         ds_put_format(&ctx->output, "%s\n", node->value);
1376     }
1377     smap_destroy(&lrs);
1378     free(nodes);
1379 }
1380
1381 static const struct nbrec_dhcp_options *
1382 dhcp_options_get(struct ctl_context *ctx, const char *id, bool must_exist)
1383 {
1384     struct uuid dhcp_opts_uuid;
1385     const struct nbrec_dhcp_options *dhcp_opts = NULL;
1386     if (uuid_from_string(&dhcp_opts_uuid, id)) {
1387         dhcp_opts = nbrec_dhcp_options_get_for_uuid(ctx->idl, &dhcp_opts_uuid);
1388     }
1389
1390     if (!dhcp_opts && must_exist) {
1391         ctl_fatal("%s: dhcp options UUID not found", id);
1392     }
1393     return dhcp_opts;
1394 }
1395
1396 static void
1397 nbctl_dhcp_options_create(struct ctl_context *ctx)
1398 {
1399     /* Validate the cidr */
1400     ovs_be32 ip;
1401     unsigned int plen;
1402     char *error = ip_parse_cidr(ctx->argv[1], &ip, &plen);
1403     if (error){
1404         /* check if its IPv6 cidr */
1405         free(error);
1406         struct in6_addr ipv6;
1407         error = ipv6_parse_cidr(ctx->argv[1], &ipv6, &plen);
1408         if (error) {
1409             free(error);
1410             ctl_fatal("Invalid cidr format '%s'", ctx->argv[1]);
1411             return;
1412         }
1413     }
1414
1415     struct nbrec_dhcp_options *dhcp_opts = nbrec_dhcp_options_insert(ctx->txn);
1416     nbrec_dhcp_options_set_cidr(dhcp_opts, ctx->argv[1]);
1417
1418     struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
1419     for (size_t i = 2; i < ctx->argc; i++) {
1420         char *key, *value;
1421         value = xstrdup(ctx->argv[i]);
1422         key = strsep(&value, "=");
1423         if (value) {
1424             smap_add(&ext_ids, key, value);
1425         }
1426         free(key);
1427     }
1428
1429     nbrec_dhcp_options_set_external_ids(dhcp_opts, &ext_ids);
1430     smap_destroy(&ext_ids);
1431 }
1432
1433 static void
1434 nbctl_dhcp_options_set_options(struct ctl_context *ctx)
1435 {
1436     const struct nbrec_dhcp_options *dhcp_opts = dhcp_options_get(
1437         ctx, ctx->argv[1], true);
1438
1439     struct smap dhcp_options = SMAP_INITIALIZER(&dhcp_options);
1440     for (size_t i = 2; i < ctx->argc; i++) {
1441         char *key, *value;
1442         value = xstrdup(ctx->argv[i]);
1443         key = strsep(&value, "=");
1444         if (value) {
1445             smap_add(&dhcp_options, key, value);
1446         }
1447         free(key);
1448     }
1449
1450     nbrec_dhcp_options_set_options(dhcp_opts, &dhcp_options);
1451     smap_destroy(&dhcp_options);
1452 }
1453
1454 static void
1455 nbctl_dhcp_options_get_options(struct ctl_context *ctx)
1456 {
1457     const struct nbrec_dhcp_options *dhcp_opts = dhcp_options_get(
1458         ctx, ctx->argv[1], true);
1459
1460     struct smap_node *node;
1461     SMAP_FOR_EACH(node, &dhcp_opts->options) {
1462         ds_put_format(&ctx->output, "%s=%s\n", node->key, node->value);
1463     }
1464 }
1465
1466 static void
1467 nbctl_dhcp_options_del(struct ctl_context *ctx)
1468 {
1469     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1470     const char *id = ctx->argv[1];
1471     const struct nbrec_dhcp_options *dhcp_opts;
1472
1473     dhcp_opts = dhcp_options_get(ctx, id, must_exist);
1474     if (!dhcp_opts) {
1475         return;
1476     }
1477
1478     nbrec_dhcp_options_delete(dhcp_opts);
1479 }
1480
1481 static void
1482 nbctl_dhcp_options_list(struct ctl_context *ctx)
1483 {
1484     const struct nbrec_dhcp_options *dhcp_opts;
1485     struct smap dhcp_options;
1486
1487     smap_init(&dhcp_options);
1488     NBREC_DHCP_OPTIONS_FOR_EACH(dhcp_opts, ctx->idl) {
1489         smap_add_format(&dhcp_options, dhcp_opts->cidr, UUID_FMT,
1490                         UUID_ARGS(&dhcp_opts->header_.uuid));
1491     }
1492     const struct smap_node **nodes = smap_sort(&dhcp_options);
1493     for (size_t i = 0; i < smap_count(&dhcp_options); i++) {
1494         const struct smap_node *node = nodes[i];
1495         ds_put_format(&ctx->output, "%s\n", node->value);
1496     }
1497     smap_destroy(&dhcp_options);
1498     free(nodes);
1499 }
1500
1501 /* The caller must free the returned string. */
1502 static char *
1503 normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen)
1504 {
1505     ovs_be32 network = ipv4 & be32_prefix_mask(plen);
1506     if (plen == 32) {
1507         return xasprintf(IP_FMT, IP_ARGS(network));
1508     } else {
1509         return xasprintf(IP_FMT"/%d", IP_ARGS(network), plen);
1510     }
1511 }
1512
1513 /* The caller must free the returned string. */
1514 static char *
1515 normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen)
1516 {
1517     char network_s[INET6_ADDRSTRLEN];
1518
1519     struct in6_addr mask = ipv6_create_mask(plen);
1520     struct in6_addr network = ipv6_addr_bitand(&ipv6, &mask);
1521
1522     inet_ntop(AF_INET6, &network, network_s, INET6_ADDRSTRLEN);
1523     if (plen == 128) {
1524         return xasprintf("%s", network_s);
1525     } else {
1526         return xasprintf("%s/%d", network_s, plen);
1527     }
1528 }
1529
1530 /* The caller must free the returned string. */
1531 static char *
1532 normalize_prefix_str(const char *orig_prefix)
1533 {
1534     unsigned int plen;
1535     ovs_be32 ipv4;
1536     char *error;
1537
1538     error = ip_parse_cidr(orig_prefix, &ipv4, &plen);
1539     if (!error) {
1540         return normalize_ipv4_prefix(ipv4, plen);
1541     } else {
1542         struct in6_addr ipv6;
1543         free(error);
1544
1545         error = ipv6_parse_cidr(orig_prefix, &ipv6, &plen);
1546         if (error) {
1547             free(error);
1548             return NULL;
1549         }
1550         return normalize_ipv6_prefix(ipv6, plen);
1551     }
1552 }
1553 \f
1554 static void
1555 nbctl_lr_route_add(struct ctl_context *ctx)
1556 {
1557     const struct nbrec_logical_router *lr;
1558     lr = lr_by_name_or_uuid(ctx, ctx->argv[1], true);
1559     char *prefix, *next_hop;
1560
1561     prefix = normalize_prefix_str(ctx->argv[2]);
1562     if (!prefix) {
1563         ctl_fatal("bad prefix argument: %s", ctx->argv[2]);
1564     }
1565
1566     next_hop = normalize_prefix_str(ctx->argv[3]);
1567     if (!next_hop) {
1568         ctl_fatal("bad next hop argument: %s", ctx->argv[3]);
1569     }
1570
1571     if (strchr(prefix, '.')) {
1572         ovs_be32 hop_ipv4;
1573         if (!ip_parse(ctx->argv[3], &hop_ipv4)) {
1574             ctl_fatal("bad IPv4 nexthop argument: %s", ctx->argv[3]);
1575         }
1576     } else {
1577         struct in6_addr hop_ipv6;
1578         if (!ipv6_parse(ctx->argv[3], &hop_ipv6)) {
1579             ctl_fatal("bad IPv6 nexthop argument: %s", ctx->argv[3]);
1580         }
1581     }
1582
1583     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1584     for (int i = 0; i < lr->n_static_routes; i++) {
1585         const struct nbrec_logical_router_static_route *route
1586             = lr->static_routes[i];
1587         char *rt_prefix;
1588
1589         rt_prefix = normalize_prefix_str(lr->static_routes[i]->ip_prefix);
1590         if (!rt_prefix) {
1591             /* Ignore existing prefix we couldn't parse. */
1592             continue;
1593         }
1594
1595         if (strcmp(rt_prefix, prefix)) {
1596             free(rt_prefix);
1597             continue;
1598         }
1599
1600         if (!may_exist) {
1601             ctl_fatal("duplicate prefix: %s", prefix);
1602         }
1603
1604         /* Update the next hop for an existing route. */
1605         nbrec_logical_router_verify_static_routes(lr);
1606         nbrec_logical_router_static_route_verify_ip_prefix(route);
1607         nbrec_logical_router_static_route_verify_nexthop(route);
1608         nbrec_logical_router_static_route_set_ip_prefix(route, prefix);
1609         nbrec_logical_router_static_route_set_nexthop(route, next_hop);
1610         if (ctx->argc == 5) {
1611             nbrec_logical_router_static_route_set_output_port(route,
1612                                                               ctx->argv[4]);
1613         }
1614         free(rt_prefix);
1615         free(next_hop);
1616         free(prefix);
1617         return;
1618     }
1619
1620     struct nbrec_logical_router_static_route *route;
1621     route = nbrec_logical_router_static_route_insert(ctx->txn);
1622     nbrec_logical_router_static_route_set_ip_prefix(route, prefix);
1623     nbrec_logical_router_static_route_set_nexthop(route, next_hop);
1624     if (ctx->argc == 5) {
1625         nbrec_logical_router_static_route_set_output_port(route, ctx->argv[4]);
1626     }
1627
1628     nbrec_logical_router_verify_static_routes(lr);
1629     struct nbrec_logical_router_static_route **new_routes
1630         = xmalloc(sizeof *new_routes * (lr->n_static_routes + 1));
1631     memcpy(new_routes, lr->static_routes,
1632            sizeof *new_routes * lr->n_static_routes);
1633     new_routes[lr->n_static_routes] = route;
1634     nbrec_logical_router_set_static_routes(lr, new_routes,
1635                                            lr->n_static_routes + 1);
1636     free(new_routes);
1637     free(next_hop);
1638     free(prefix);
1639 }
1640
1641 static void
1642 nbctl_lr_route_del(struct ctl_context *ctx)
1643 {
1644     const struct nbrec_logical_router *lr;
1645     lr = lr_by_name_or_uuid(ctx, ctx->argv[1], true);
1646
1647     if (ctx->argc == 2) {
1648         /* If a prefix is not specified, delete all routes. */
1649         nbrec_logical_router_set_static_routes(lr, NULL, 0);
1650         return;
1651     }
1652
1653     char *prefix = normalize_prefix_str(ctx->argv[2]);
1654     if (!prefix) {
1655         ctl_fatal("bad prefix argument: %s", ctx->argv[2]);
1656     }
1657
1658     for (int i = 0; i < lr->n_static_routes; i++) {
1659         char *rt_prefix = normalize_prefix_str(lr->static_routes[i]->ip_prefix);
1660         if (!rt_prefix) {
1661             /* Ignore existing prefix we couldn't parse. */
1662             continue;
1663         }
1664
1665         if (!strcmp(prefix, rt_prefix)) {
1666             struct nbrec_logical_router_static_route **new_routes
1667                 = xmemdup(lr->static_routes,
1668                           sizeof *new_routes * lr->n_static_routes);
1669
1670             new_routes[i] = lr->static_routes[lr->n_static_routes - 1];
1671             nbrec_logical_router_verify_static_routes(lr);
1672             nbrec_logical_router_set_static_routes(lr, new_routes,
1673                                                  lr->n_static_routes - 1);
1674             free(new_routes);
1675             free(rt_prefix);
1676             free(prefix);
1677             return;
1678         }
1679         free(rt_prefix);
1680     }
1681
1682     if (!shash_find(&ctx->options, "--if-exists")) {
1683         ctl_fatal("no matching prefix: %s", prefix);
1684     }
1685     free(prefix);
1686 }
1687 \f
1688 static const struct nbrec_logical_router_port *
1689 lrp_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist)
1690 {
1691     const struct nbrec_logical_router_port *lrp = NULL;
1692
1693     struct uuid lrp_uuid;
1694     bool is_uuid = uuid_from_string(&lrp_uuid, id);
1695     if (is_uuid) {
1696         lrp = nbrec_logical_router_port_get_for_uuid(ctx->idl, &lrp_uuid);
1697     }
1698
1699     if (!lrp) {
1700         NBREC_LOGICAL_ROUTER_PORT_FOR_EACH(lrp, ctx->idl) {
1701             if (!strcmp(lrp->name, id)) {
1702                 break;
1703             }
1704         }
1705     }
1706
1707     if (!lrp && must_exist) {
1708         ctl_fatal("%s: port %s not found", id, is_uuid ? "UUID" : "name");
1709     }
1710
1711     return lrp;
1712 }
1713
1714 /* Returns the logical router that contains 'lrp'. */
1715 static const struct nbrec_logical_router *
1716 lrp_to_lr(const struct ovsdb_idl *idl,
1717                const struct nbrec_logical_router_port *lrp)
1718 {
1719     const struct nbrec_logical_router *lr;
1720     NBREC_LOGICAL_ROUTER_FOR_EACH (lr, idl) {
1721         for (size_t i = 0; i < lr->n_ports; i++) {
1722             if (lr->ports[i] == lrp) {
1723                 return lr;
1724             }
1725         }
1726     }
1727
1728     /* Can't happen because of the database schema */
1729     ctl_fatal("port %s is not part of any logical router",
1730               lrp->name);
1731 }
1732
1733 static const char *
1734 lr_get_name(const struct nbrec_logical_router *lr, char uuid_s[UUID_LEN + 1],
1735             size_t uuid_s_size)
1736 {
1737     if (lr->name[0]) {
1738         return lr->name;
1739     }
1740     snprintf(uuid_s, uuid_s_size, UUID_FMT, UUID_ARGS(&lr->header_.uuid));
1741     return uuid_s;
1742 }
1743
1744 static void
1745 nbctl_lrp_add(struct ctl_context *ctx)
1746 {
1747     bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1748
1749     const struct nbrec_logical_router *lr;
1750     lr = lr_by_name_or_uuid(ctx, ctx->argv[1], true);
1751
1752     const char *lrp_name = ctx->argv[2];
1753     const char *mac = ctx->argv[3];
1754     const char **networks = (const char **) &ctx->argv[4];
1755
1756     int n_networks = ctx->argc - 4;
1757     for (int i = 4; i < ctx->argc; i++) {
1758         if (strchr(ctx->argv[i], '=')) {
1759             n_networks = i - 4;
1760             break;
1761         }
1762     }
1763
1764     if (!n_networks) {
1765         ctl_fatal("%s: router port requires specifying a network", lrp_name);
1766     }
1767
1768     char **settings = (char **) &ctx->argv[n_networks + 4];
1769     int n_settings = ctx->argc - 4 - n_networks;
1770
1771     const struct nbrec_logical_router_port *lrp;
1772     lrp = lrp_by_name_or_uuid(ctx, lrp_name, false);
1773     if (lrp) {
1774         if (!may_exist) {
1775             ctl_fatal("%s: a port with this name already exists",
1776                       lrp_name);
1777         }
1778
1779         const struct nbrec_logical_router *bound_lr;
1780         bound_lr = lrp_to_lr(ctx->idl, lrp);
1781         if (bound_lr != lr) {
1782             char uuid_s[UUID_LEN + 1];
1783             ctl_fatal("%s: port already exists but in router %s", lrp_name,
1784                       lr_get_name(bound_lr, uuid_s, sizeof uuid_s));
1785         }
1786
1787         if (strcmp(mac, lrp->mac)) {
1788             ctl_fatal("%s: port already exists with mac %s", lrp_name,
1789                       lrp->mac);
1790         }
1791
1792         struct sset new_networks = SSET_INITIALIZER(&new_networks);
1793         for (int i = 0; i < n_networks; i++) {
1794             sset_add(&new_networks, networks[i]);
1795         }
1796
1797         struct sset orig_networks = SSET_INITIALIZER(&orig_networks);
1798         sset_add_array(&orig_networks, lrp->networks, lrp->n_networks);
1799
1800         if (!sset_equals(&orig_networks, &new_networks)) {
1801             ctl_fatal("%s: port already exists with different network",
1802                       lrp_name);
1803         }
1804
1805         sset_destroy(&orig_networks);
1806         sset_destroy(&new_networks);
1807
1808         /* Special-case sanity-check of peer ports. */
1809         const char *peer = NULL;
1810         for (int i = 0; i < n_settings; i++) {
1811             if (!strncmp(settings[i], "peer=", 5)) {
1812                 peer = settings[i] + 5;
1813                 break;
1814             }
1815         }
1816
1817         if ((!peer != !lrp->peer) ||
1818                 (lrp->peer && strcmp(peer, lrp->peer))) {
1819             ctl_fatal("%s: port already exists with mismatching peer",
1820                       lrp_name);
1821         }
1822
1823         return;
1824     }
1825
1826     struct eth_addr ea;
1827     if (!ovs_scan(mac, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(ea))) {
1828         ctl_fatal("%s: invalid mac address %s", lrp_name, mac);
1829     }
1830
1831     for (int i = 0; i < n_networks; i++) {
1832         ovs_be32 ipv4;
1833         unsigned int plen;
1834         char *error = ip_parse_cidr(networks[i], &ipv4, &plen);
1835         if (error) {
1836             free(error);
1837             struct in6_addr ipv6;
1838             error = ipv6_parse_cidr(networks[i], &ipv6, &plen);
1839             if (error) {
1840                 free(error);
1841                 ctl_fatal("%s: invalid network address: %s", lrp_name,
1842                           networks[i]);
1843             }
1844         }
1845     }
1846
1847     /* Create the logical port. */
1848     lrp = nbrec_logical_router_port_insert(ctx->txn);
1849     nbrec_logical_router_port_set_name(lrp, lrp_name);
1850     nbrec_logical_router_port_set_mac(lrp, mac);
1851     nbrec_logical_router_port_set_networks(lrp, networks, n_networks);
1852
1853     for (int i = 0; i < n_settings; i++) {
1854         ctl_set_column("Logical_Router_Port", &lrp->header_, settings[i],
1855                        ctx->symtab);
1856     }
1857
1858     /* Insert the logical port into the logical router. */
1859     nbrec_logical_router_verify_ports(lr);
1860     struct nbrec_logical_router_port **new_ports = xmalloc(sizeof *new_ports *
1861                                                         (lr->n_ports + 1));
1862     memcpy(new_ports, lr->ports, sizeof *new_ports * lr->n_ports);
1863     new_ports[lr->n_ports] = CONST_CAST(struct nbrec_logical_router_port *,
1864                                              lrp);
1865     nbrec_logical_router_set_ports(lr, new_ports, lr->n_ports + 1);
1866     free(new_ports);
1867 }
1868
1869 /* Removes logical router port 'lr->ports[idx]'. */
1870 static void
1871 remove_lrp(const struct nbrec_logical_router *lr, size_t idx)
1872 {
1873     const struct nbrec_logical_router_port *lrp = lr->ports[idx];
1874
1875     /* First remove 'lrp' from the array of ports.  This is what will
1876      * actually cause the logical port to be deleted when the transaction is
1877      * sent to the database server (due to garbage collection). */
1878     struct nbrec_logical_router_port **new_ports
1879         = xmemdup(lr->ports, sizeof *new_ports * lr->n_ports);
1880     new_ports[idx] = new_ports[lr->n_ports - 1];
1881     nbrec_logical_router_verify_ports(lr);
1882     nbrec_logical_router_set_ports(lr, new_ports, lr->n_ports - 1);
1883     free(new_ports);
1884
1885     /* Delete 'lrp' from the IDL.  This won't have a real effect on
1886      * the database server (the IDL will suppress it in fact) but it
1887      * means that it won't show up when we iterate with
1888      * NBREC_LOGICAL_ROUTER_PORT_FOR_EACH later. */
1889     nbrec_logical_router_port_delete(lrp);
1890 }
1891
1892 static void
1893 nbctl_lrp_del(struct ctl_context *ctx)
1894 {
1895     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1896     const struct nbrec_logical_router_port *lrp;
1897
1898     lrp = lrp_by_name_or_uuid(ctx, ctx->argv[1], must_exist);
1899     if (!lrp) {
1900         return;
1901     }
1902
1903     /* Find the router that contains 'lrp', then delete it. */
1904     const struct nbrec_logical_router *lr;
1905     NBREC_LOGICAL_ROUTER_FOR_EACH (lr, ctx->idl) {
1906         for (size_t i = 0; i < lr->n_ports; i++) {
1907             if (lr->ports[i] == lrp) {
1908                 remove_lrp(lr, i);
1909                 return;
1910             }
1911         }
1912     }
1913
1914     /* Can't happen because of the database schema. */
1915     ctl_fatal("logical port %s is not part of any logical router",
1916               ctx->argv[1]);
1917 }
1918
1919 /* Print a list of logical router ports. */
1920 static void
1921 nbctl_lrp_list(struct ctl_context *ctx)
1922 {
1923     const char *id = ctx->argv[1];
1924     const struct nbrec_logical_router *lr;
1925     struct smap lrps;
1926     size_t i;
1927
1928     lr = lr_by_name_or_uuid(ctx, id, true);
1929
1930     smap_init(&lrps);
1931     for (i = 0; i < lr->n_ports; i++) {
1932         const struct nbrec_logical_router_port *lrp = lr->ports[i];
1933         smap_add_format(&lrps, lrp->name, UUID_FMT " (%s)",
1934                         UUID_ARGS(&lrp->header_.uuid), lrp->name);
1935     }
1936     const struct smap_node **nodes = smap_sort(&lrps);
1937     for (i = 0; i < smap_count(&lrps); i++) {
1938         const struct smap_node *node = nodes[i];
1939         ds_put_format(&ctx->output, "%s\n", node->value);
1940     }
1941     smap_destroy(&lrps);
1942     free(nodes);
1943 }
1944
1945 /* Set the logical router port admin-enabled state. */
1946 static void
1947 nbctl_lrp_set_enabled(struct ctl_context *ctx)
1948 {
1949     const char *id = ctx->argv[1];
1950     const char *state = ctx->argv[2];
1951     const struct nbrec_logical_router_port *lrp;
1952
1953     lrp = lrp_by_name_or_uuid(ctx, id, true);
1954     if (!lrp) {
1955         return;
1956     }
1957
1958     bool enabled = parse_enabled(state);
1959     nbrec_logical_router_port_set_enabled(lrp, &enabled, 1);
1960 }
1961
1962 /* Print admin-enabled state for logical router port. */
1963 static void
1964 nbctl_lrp_get_enabled(struct ctl_context *ctx)
1965 {
1966     const char *id = ctx->argv[1];
1967     const struct nbrec_logical_router_port *lrp;
1968
1969     lrp = lrp_by_name_or_uuid(ctx, id, true);
1970     if (!lrp) {
1971         return;
1972     }
1973
1974     ds_put_format(&ctx->output, "%s\n",
1975                   !lrp->enabled ||
1976                   *lrp->enabled ? "enabled" : "disabled");
1977 }
1978 \f
1979 struct ipv4_route {
1980     int plen;
1981     ovs_be32 addr;
1982     const struct nbrec_logical_router_static_route *route;
1983 };
1984
1985 static int
1986 ipv4_route_cmp(const void *route1_, const void *route2_)
1987 {
1988     const struct ipv4_route *route1p = route1_;
1989     const struct ipv4_route *route2p = route2_;
1990
1991     if (route1p->plen != route2p->plen) {
1992         return route1p->plen > route2p->plen ? -1 : 1;
1993     } else if (route1p->addr != route2p->addr) {
1994         return ntohl(route1p->addr) < ntohl(route2p->addr) ? -1 : 1;
1995     } else {
1996         return 0;
1997     }
1998 }
1999
2000 struct ipv6_route {
2001     int plen;
2002     struct in6_addr addr;
2003     const struct nbrec_logical_router_static_route *route;
2004 };
2005
2006 static int
2007 ipv6_route_cmp(const void *route1_, const void *route2_)
2008 {
2009     const struct ipv6_route *route1p = route1_;
2010     const struct ipv6_route *route2p = route2_;
2011
2012     if (route1p->plen != route2p->plen) {
2013         return route1p->plen > route2p->plen ? -1 : 1;
2014     }
2015     return memcmp(&route1p->addr, &route2p->addr, sizeof(route1p->addr));
2016 }
2017
2018 static void
2019 print_route(const struct nbrec_logical_router_static_route *route, struct ds *s)
2020 {
2021
2022     char *prefix = normalize_prefix_str(route->ip_prefix);
2023     char *next_hop = normalize_prefix_str(route->nexthop);
2024     ds_put_format(s, "%25s %25s", prefix, next_hop);
2025     free(prefix);
2026     free(next_hop);
2027
2028     if (route->output_port) {
2029         ds_put_format(s, " %s", route->output_port);
2030     }
2031     ds_put_char(s, '\n');
2032 }
2033
2034 static void
2035 nbctl_lr_route_list(struct ctl_context *ctx)
2036 {
2037     const struct nbrec_logical_router *lr;
2038     struct ipv4_route *ipv4_routes;
2039     struct ipv6_route *ipv6_routes;
2040     size_t n_ipv4_routes = 0;
2041     size_t n_ipv6_routes = 0;
2042
2043     lr = lr_by_name_or_uuid(ctx, ctx->argv[1], true);
2044
2045     ipv4_routes = xmalloc(sizeof *ipv4_routes * lr->n_static_routes);
2046     ipv6_routes = xmalloc(sizeof *ipv6_routes * lr->n_static_routes);
2047
2048     for (int i = 0; i < lr->n_static_routes; i++) {
2049         const struct nbrec_logical_router_static_route *route
2050             = lr->static_routes[i];
2051         unsigned int plen;
2052         ovs_be32 ipv4;
2053         char *error;
2054
2055         error = ip_parse_cidr(route->ip_prefix, &ipv4, &plen);
2056         if (!error) {
2057             ipv4_routes[n_ipv4_routes].plen = plen;
2058             ipv4_routes[n_ipv4_routes].addr = ipv4;
2059             ipv4_routes[n_ipv4_routes].route = route;
2060             n_ipv4_routes++;
2061         } else {
2062             free(error);
2063
2064             struct in6_addr ipv6;
2065             error = ipv6_parse_cidr(route->ip_prefix, &ipv6, &plen);
2066             if (!error) {
2067                 ipv6_routes[n_ipv6_routes].plen = plen;
2068                 ipv6_routes[n_ipv6_routes].addr = ipv6;
2069                 ipv6_routes[n_ipv6_routes].route = route;
2070                 n_ipv6_routes++;
2071             } else {
2072                 /* Invalid prefix. */
2073                 VLOG_WARN("router "UUID_FMT" (%s) has invalid prefix: %s",
2074                           UUID_ARGS(&lr->header_.uuid), lr->name,
2075                           route->ip_prefix);
2076                 free(error);
2077                 continue;
2078             }
2079         }
2080     }
2081
2082     qsort(ipv4_routes, n_ipv4_routes, sizeof *ipv4_routes, ipv4_route_cmp);
2083     qsort(ipv6_routes, n_ipv6_routes, sizeof *ipv6_routes, ipv6_route_cmp);
2084
2085     if (n_ipv4_routes) {
2086         ds_put_cstr(&ctx->output, "IPv4 Routes\n");
2087     }
2088     for (int i = 0; i < n_ipv4_routes; i++) {
2089         print_route(ipv4_routes[i].route, &ctx->output);
2090     }
2091
2092     if (n_ipv6_routes) {
2093         ds_put_format(&ctx->output, "%sIPv6 Routes\n",
2094                       n_ipv4_routes ?  "\n" : "");
2095     }
2096     for (int i = 0; i < n_ipv6_routes; i++) {
2097         print_route(ipv6_routes[i].route, &ctx->output);
2098     }
2099
2100     free(ipv4_routes);
2101     free(ipv6_routes);
2102 }
2103
2104 static const struct ctl_table_class tables[] = {
2105     {&nbrec_table_nb_global,
2106      {{&nbrec_table_nb_global, NULL, NULL},
2107       {NULL, NULL, NULL}}},
2108
2109     {&nbrec_table_logical_switch,
2110      {{&nbrec_table_logical_switch, &nbrec_logical_switch_col_name, NULL},
2111       {NULL, NULL, NULL}}},
2112
2113     {&nbrec_table_logical_switch_port,
2114      {{&nbrec_table_logical_switch_port, &nbrec_logical_switch_port_col_name,
2115        NULL},
2116       {NULL, NULL, NULL}}},
2117
2118     {&nbrec_table_acl,
2119      {{NULL, NULL, NULL},
2120       {NULL, NULL, NULL}}},
2121
2122     {&nbrec_table_load_balancer,
2123      {{NULL, NULL, NULL},
2124       {NULL, NULL, NULL}}},
2125
2126     {&nbrec_table_logical_router,
2127      {{&nbrec_table_logical_router, &nbrec_logical_router_col_name, NULL},
2128       {NULL, NULL, NULL}}},
2129
2130     {&nbrec_table_logical_router_port,
2131      {{&nbrec_table_logical_router_port, &nbrec_logical_router_port_col_name,
2132        NULL},
2133       {NULL, NULL, NULL}}},
2134
2135     {&nbrec_table_logical_router_static_route,
2136      {{&nbrec_table_logical_router_static_route, NULL,
2137        NULL},
2138       {NULL, NULL, NULL}}},
2139
2140     {&nbrec_table_nat,
2141      {{&nbrec_table_nat, NULL,
2142        NULL},
2143       {NULL, NULL, NULL}}},
2144
2145     {&nbrec_table_address_set,
2146      {{&nbrec_table_address_set, &nbrec_address_set_col_name, NULL},
2147       {NULL, NULL, NULL}}},
2148
2149     {&nbrec_table_dhcp_options,
2150      {{&nbrec_table_dhcp_options, NULL,
2151        NULL},
2152       {NULL, NULL, NULL}}},
2153
2154     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
2155 };
2156 \f
2157 static void
2158 run_prerequisites(struct ctl_command *commands, size_t n_commands,
2159                   struct ovsdb_idl *idl)
2160 {
2161     ovsdb_idl_add_table(idl, &nbrec_table_nb_global);
2162     if (wait_type == NBCTL_WAIT_SB) {
2163         ovsdb_idl_add_column(idl, &nbrec_nb_global_col_sb_cfg);
2164     } else if (wait_type == NBCTL_WAIT_HV) {
2165         ovsdb_idl_add_column(idl, &nbrec_nb_global_col_hv_cfg);
2166     }
2167
2168     for (struct ctl_command *c = commands; c < &commands[n_commands]; c++) {
2169         if (c->syntax->prerequisites) {
2170             struct ctl_context ctx;
2171
2172             ds_init(&c->output);
2173             c->table = NULL;
2174
2175             ctl_context_init(&ctx, c, idl, NULL, NULL, NULL);
2176             (c->syntax->prerequisites)(&ctx);
2177             ctl_context_done(&ctx, c);
2178
2179             ovs_assert(!c->output.string);
2180             ovs_assert(!c->table);
2181         }
2182     }
2183 }
2184
2185 static bool
2186 do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
2187          struct ovsdb_idl *idl)
2188 {
2189     struct ovsdb_idl_txn *txn;
2190     enum ovsdb_idl_txn_status status;
2191     struct ovsdb_symbol_table *symtab;
2192     struct ctl_context ctx;
2193     struct ctl_command *c;
2194     struct shash_node *node;
2195     int64_t next_cfg = 0;
2196     char *error = NULL;
2197
2198     txn = the_idl_txn = ovsdb_idl_txn_create(idl);
2199     if (dry_run) {
2200         ovsdb_idl_txn_set_dry_run(txn);
2201     }
2202
2203     ovsdb_idl_txn_add_comment(txn, "ovs-nbctl: %s", args);
2204
2205     const struct nbrec_nb_global *nb = nbrec_nb_global_first(idl);
2206     if (!nb) {
2207         /* XXX add verification that table is empty */
2208         nb = nbrec_nb_global_insert(txn);
2209     }
2210
2211     if (wait_type != NBCTL_WAIT_NONE) {
2212         ovsdb_idl_txn_increment(txn, &nb->header_,
2213                                 &nbrec_nb_global_col_nb_cfg);
2214     }
2215
2216     symtab = ovsdb_symbol_table_create();
2217     for (c = commands; c < &commands[n_commands]; c++) {
2218         ds_init(&c->output);
2219         c->table = NULL;
2220     }
2221     ctl_context_init(&ctx, NULL, idl, txn, symtab, NULL);
2222     for (c = commands; c < &commands[n_commands]; c++) {
2223         ctl_context_init_command(&ctx, c);
2224         if (c->syntax->run) {
2225             (c->syntax->run)(&ctx);
2226         }
2227         ctl_context_done_command(&ctx, c);
2228
2229         if (ctx.try_again) {
2230             ctl_context_done(&ctx, NULL);
2231             goto try_again;
2232         }
2233     }
2234     ctl_context_done(&ctx, NULL);
2235
2236     SHASH_FOR_EACH (node, &symtab->sh) {
2237         struct ovsdb_symbol *symbol = node->data;
2238         if (!symbol->created) {
2239             ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
2240                       "with \"-- --id=%s create ...\")",
2241                       node->name, node->name);
2242         }
2243         if (!symbol->strong_ref) {
2244             if (!symbol->weak_ref) {
2245                 VLOG_WARN("row id \"%s\" was created but no reference to it "
2246                           "was inserted, so it will not actually appear in "
2247                           "the database", node->name);
2248             } else {
2249                 VLOG_WARN("row id \"%s\" was created but only a weak "
2250                           "reference to it was inserted, so it will not "
2251                           "actually appear in the database", node->name);
2252             }
2253         }
2254     }
2255
2256     status = ovsdb_idl_txn_commit_block(txn);
2257     if (wait_type != NBCTL_WAIT_NONE && status == TXN_SUCCESS) {
2258         next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
2259     }
2260     if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
2261         for (c = commands; c < &commands[n_commands]; c++) {
2262             if (c->syntax->postprocess) {
2263                 ctl_context_init(&ctx, c, idl, txn, symtab, NULL);
2264                 (c->syntax->postprocess)(&ctx);
2265                 ctl_context_done(&ctx, c);
2266             }
2267         }
2268     }
2269     error = xstrdup(ovsdb_idl_txn_get_error(txn));
2270
2271     switch (status) {
2272     case TXN_UNCOMMITTED:
2273     case TXN_INCOMPLETE:
2274         OVS_NOT_REACHED();
2275
2276     case TXN_ABORTED:
2277         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
2278         ctl_fatal("transaction aborted");
2279
2280     case TXN_UNCHANGED:
2281     case TXN_SUCCESS:
2282         break;
2283
2284     case TXN_TRY_AGAIN:
2285         goto try_again;
2286
2287     case TXN_ERROR:
2288         ctl_fatal("transaction error: %s", error);
2289
2290     case TXN_NOT_LOCKED:
2291         /* Should not happen--we never call ovsdb_idl_set_lock(). */
2292         ctl_fatal("database not locked");
2293
2294     default:
2295         OVS_NOT_REACHED();
2296     }
2297     free(error);
2298
2299     ovsdb_symbol_table_destroy(symtab);
2300
2301     for (c = commands; c < &commands[n_commands]; c++) {
2302         struct ds *ds = &c->output;
2303
2304         if (c->table) {
2305             table_print(c->table, &table_style);
2306         } else if (oneline) {
2307             size_t j;
2308
2309             ds_chomp(ds, '\n');
2310             for (j = 0; j < ds->length; j++) {
2311                 int ch = ds->string[j];
2312                 switch (ch) {
2313                 case '\n':
2314                     fputs("\\n", stdout);
2315                     break;
2316
2317                 case '\\':
2318                     fputs("\\\\", stdout);
2319                     break;
2320
2321                 default:
2322                     putchar(ch);
2323                 }
2324             }
2325             putchar('\n');
2326         } else {
2327             fputs(ds_cstr(ds), stdout);
2328         }
2329         ds_destroy(&c->output);
2330         table_destroy(c->table);
2331         free(c->table);
2332
2333         shash_destroy_free_data(&c->options);
2334     }
2335     free(commands);
2336
2337     if (wait_type != NBCTL_WAIT_NONE && status != TXN_UNCHANGED) {
2338         ovsdb_idl_enable_reconnect(idl);
2339         for (;;) {
2340             ovsdb_idl_run(idl);
2341             NBREC_NB_GLOBAL_FOR_EACH (nb, idl) {
2342                 int64_t cur_cfg = (wait_type == NBCTL_WAIT_SB
2343                                    ? nb->sb_cfg
2344                                    : nb->hv_cfg);
2345                 if (cur_cfg >= next_cfg) {
2346                     goto done;
2347                 }
2348             }
2349             ovsdb_idl_wait(idl);
2350             poll_block();
2351         }
2352     done: ;
2353     }
2354
2355     ovsdb_idl_txn_destroy(txn);
2356     ovsdb_idl_destroy(idl);
2357
2358     return true;
2359
2360 try_again:
2361     /* Our transaction needs to be rerun, or a prerequisite was not met.  Free
2362      * resources and return so that the caller can try again. */
2363     if (txn) {
2364         ovsdb_idl_txn_abort(txn);
2365         ovsdb_idl_txn_destroy(txn);
2366         the_idl_txn = NULL;
2367     }
2368     ovsdb_symbol_table_destroy(symtab);
2369     for (c = commands; c < &commands[n_commands]; c++) {
2370         ds_destroy(&c->output);
2371         table_destroy(c->table);
2372         free(c->table);
2373     }
2374     free(error);
2375     return false;
2376 }
2377
2378 /* Frees the current transaction and the underlying IDL and then calls
2379  * exit(status).
2380  *
2381  * Freeing the transaction and the IDL is not strictly necessary, but it makes
2382  * for a clean memory leak report from valgrind in the normal case.  That makes
2383  * it easier to notice real memory leaks. */
2384 static void
2385 nbctl_exit(int status)
2386 {
2387     if (the_idl_txn) {
2388         ovsdb_idl_txn_abort(the_idl_txn);
2389         ovsdb_idl_txn_destroy(the_idl_txn);
2390     }
2391     ovsdb_idl_destroy(the_idl);
2392     exit(status);
2393 }
2394
2395 static const struct ctl_command_syntax nbctl_commands[] = {
2396     { "init", 0, 0, "", NULL, nbctl_init, NULL, "", RW },
2397     { "show", 0, 1, "[SWITCH]", NULL, nbctl_show, NULL, "", RO },
2398
2399     /* logical switch commands. */
2400     { "ls-add", 0, 1, "[SWITCH]", NULL, nbctl_ls_add, NULL,
2401       "--may-exist,--add-duplicate", RW },
2402     { "ls-del", 1, 1, "SWITCH", NULL, nbctl_ls_del, NULL, "--if-exists", RW },
2403     { "ls-list", 0, 0, "", NULL, nbctl_ls_list, NULL, "", RO },
2404
2405     /* acl commands. */
2406     { "acl-add", 5, 5, "SWITCH DIRECTION PRIORITY MATCH ACTION", NULL,
2407       nbctl_acl_add, NULL, "--log", RW },
2408     { "acl-del", 1, 4, "SWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
2409       nbctl_acl_del, NULL, "", RW },
2410     { "acl-list", 1, 1, "SWITCH", NULL, nbctl_acl_list, NULL, "", RO },
2411
2412     /* logical switch port commands. */
2413     { "lsp-add", 2, 4, "SWITCH PORT [PARENT] [TAG]", NULL, nbctl_lsp_add,
2414       NULL, "--may-exist", RW },
2415     { "lsp-del", 1, 1, "PORT", NULL, nbctl_lsp_del, NULL, "--if-exists", RW },
2416     { "lsp-list", 1, 1, "SWITCH", NULL, nbctl_lsp_list, NULL, "", RO },
2417     { "lsp-get-parent", 1, 1, "PORT", NULL, nbctl_lsp_get_parent, NULL,
2418       "", RO },
2419     { "lsp-get-tag", 1, 1, "PORT", NULL, nbctl_lsp_get_tag, NULL, "", RO },
2420     { "lsp-set-addresses", 1, INT_MAX, "PORT [ADDRESS]...", NULL,
2421       nbctl_lsp_set_addresses, NULL, "", RW },
2422     { "lsp-get-addresses", 1, 1, "PORT", NULL, nbctl_lsp_get_addresses, NULL,
2423       "", RO },
2424     { "lsp-set-port-security", 0, INT_MAX, "PORT [ADDRS]...", NULL,
2425       nbctl_lsp_set_port_security, NULL, "", RW },
2426     { "lsp-get-port-security", 1, 1, "PORT", NULL,
2427       nbctl_lsp_get_port_security, NULL, "", RO },
2428     { "lsp-get-up", 1, 1, "PORT", NULL, nbctl_lsp_get_up, NULL, "", RO },
2429     { "lsp-set-enabled", 2, 2, "PORT STATE", NULL, nbctl_lsp_set_enabled,
2430       NULL, "", RW },
2431     { "lsp-get-enabled", 1, 1, "PORT", NULL, nbctl_lsp_get_enabled, NULL,
2432       "", RO },
2433     { "lsp-set-type", 2, 2, "PORT TYPE", NULL, nbctl_lsp_set_type, NULL,
2434       "", RW },
2435     { "lsp-get-type", 1, 1, "PORT", NULL, nbctl_lsp_get_type, NULL, "", RO },
2436     { "lsp-set-options", 1, INT_MAX, "PORT KEY=VALUE [KEY=VALUE]...", NULL,
2437       nbctl_lsp_set_options, NULL, "", RW },
2438     { "lsp-get-options", 1, 1, "PORT", NULL, nbctl_lsp_get_options, NULL,
2439       "", RO },
2440     { "lsp-set-dhcpv4-options", 1, 2, "PORT [DHCP_OPT_UUID]", NULL,
2441       nbctl_lsp_set_dhcpv4_options, NULL, "", RW },
2442     { "lsp-get-dhcpv4-options", 1, 1, "PORT", NULL,
2443       nbctl_lsp_get_dhcpv4_options, NULL, "", RO },
2444
2445     /* logical router commands. */
2446     { "lr-add", 0, 1, "[ROUTER]", NULL, nbctl_lr_add, NULL,
2447       "--may-exist,--add-duplicate", RW },
2448     { "lr-del", 1, 1, "ROUTER", NULL, nbctl_lr_del, NULL, "--if-exists", RW },
2449     { "lr-list", 0, 0, "", NULL, nbctl_lr_list, NULL, "", RO },
2450
2451     /* logical router port commands. */
2452     { "lrp-add", 4, INT_MAX,
2453       "ROUTER PORT MAC NETWORK... [COLUMN[:KEY]=VALUE]...",
2454       NULL, nbctl_lrp_add, NULL, "--may-exist", RW },
2455     { "lrp-del", 1, 1, "PORT", NULL, nbctl_lrp_del, NULL, "--if-exists", RW },
2456     { "lrp-list", 1, 1, "ROUTER", NULL, nbctl_lrp_list, NULL, "", RO },
2457     { "lrp-set-enabled", 2, 2, "PORT STATE", NULL, nbctl_lrp_set_enabled,
2458       NULL, "", RW },
2459     { "lrp-get-enabled", 1, 1, "PORT", NULL, nbctl_lrp_get_enabled,
2460       NULL, "", RO },
2461
2462     /* logical router route commands. */
2463     { "lr-route-add", 3, 4, "ROUTER PREFIX NEXTHOP [PORT]", NULL,
2464       nbctl_lr_route_add, NULL, "--may-exist", RW },
2465     { "lr-route-del", 1, 2, "ROUTER [PREFIX]", NULL, nbctl_lr_route_del,
2466       NULL, "--if-exists", RW },
2467     { "lr-route-list", 1, 1, "ROUTER", NULL, nbctl_lr_route_list, NULL,
2468       "", RO },
2469
2470     /* DHCP_Options commands */
2471     {"dhcp-options-create", 1, INT_MAX, "CIDR [EXTERNAL:IDS]", NULL,
2472      nbctl_dhcp_options_create, NULL, "", RW },
2473     {"dhcp-options-del", 1, 1, "DHCP_OPT_UUID", NULL,
2474      nbctl_dhcp_options_del, NULL, "", RW},
2475     {"dhcp-options-list", 0, 0, "", NULL, nbctl_dhcp_options_list, NULL, "", RO},
2476     {"dhcp-options-set-options", 1, INT_MAX, "DHCP_OPT_UUID KEY=VALUE [KEY=VALUE]...",
2477     NULL, nbctl_dhcp_options_set_options, NULL, "", RW },
2478     {"dhcp-options-get-options", 1, 1, "DHCP_OPT_UUID", NULL,
2479      nbctl_dhcp_options_get_options, NULL, "", RO },
2480
2481     {NULL, 0, 0, NULL, NULL, NULL, NULL, "", RO},
2482 };
2483
2484 /* Registers nbctl and common db commands. */
2485 static void
2486 nbctl_cmd_init(void)
2487 {
2488     ctl_init(tables, NULL, nbctl_exit);
2489     ctl_register_commands(nbctl_commands);
2490 }