ovn-nbctl: Update show format for addresses.
[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 void 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     extern struct vlog_module VLM_reconnect;
77     struct ovsdb_idl *idl;
78     struct ctl_command *commands;
79     struct shash local_options;
80     unsigned int seqno;
81     size_t n_commands;
82     char *args;
83
84     set_program_name(argv[0]);
85     fatal_ignore_sigpipe();
86     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
87     vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
88     nbrec_init();
89
90     nbctl_cmd_init();
91
92     /* Log our arguments.  This is often valuable for debugging systems. */
93     args = process_escape_args(argv);
94     VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG,
95          "Called as %s", args);
96
97     /* Parse command line. */
98     shash_init(&local_options);
99     parse_options(argc, argv, &local_options);
100     commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
101                                   &n_commands);
102
103     if (timeout) {
104         time_alarm(timeout);
105     }
106
107     /* Initialize IDL. */
108     idl = the_idl = ovsdb_idl_create(db, &nbrec_idl_class, true, false);
109     run_prerequisites(commands, n_commands, idl);
110
111     /* Execute the commands.
112      *
113      * 'seqno' is the database sequence number for which we last tried to
114      * execute our transaction.  There's no point in trying to commit more than
115      * once for any given sequence number, because if the transaction fails
116      * it's because the database changed and we need to obtain an up-to-date
117      * view of the database before we try the transaction again. */
118     seqno = ovsdb_idl_get_seqno(idl);
119     for (;;) {
120         ovsdb_idl_run(idl);
121         if (!ovsdb_idl_is_alive(idl)) {
122             int retval = ovsdb_idl_get_last_error(idl);
123             ctl_fatal("%s: database connection failed (%s)",
124                         db, ovs_retval_to_string(retval));
125         }
126
127         if (seqno != ovsdb_idl_get_seqno(idl)) {
128             seqno = ovsdb_idl_get_seqno(idl);
129             do_nbctl(args, commands, n_commands, idl);
130         }
131
132         if (seqno == ovsdb_idl_get_seqno(idl)) {
133             ovsdb_idl_wait(idl);
134             poll_block();
135         }
136     }
137 }
138
139 static const char *
140 nbctl_default_db(void)
141 {
142     static char *def;
143     if (!def) {
144         def = getenv("OVN_NB_DB");
145         if (!def) {
146             def = ctl_default_db();
147         }
148     }
149     return def;
150 }
151
152 static void
153 parse_options(int argc, char *argv[], struct shash *local_options)
154 {
155     enum {
156         OPT_DB = UCHAR_MAX + 1,
157         OPT_NO_SYSLOG,
158         OPT_DRY_RUN,
159         OPT_ONELINE,
160         OPT_LOCAL,
161         OPT_COMMANDS,
162         OPT_OPTIONS,
163         VLOG_OPTION_ENUMS,
164         TABLE_OPTION_ENUMS
165     };
166     static const struct option global_long_options[] = {
167         {"db", required_argument, NULL, OPT_DB},
168         {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
169         {"dry-run", no_argument, NULL, OPT_DRY_RUN},
170         {"oneline", no_argument, NULL, OPT_ONELINE},
171         {"timeout", required_argument, NULL, 't'},
172         {"help", no_argument, NULL, 'h'},
173         {"commands", no_argument, NULL, OPT_COMMANDS},
174         {"options", no_argument, NULL, OPT_OPTIONS},
175         {"version", no_argument, NULL, 'V'},
176         VLOG_LONG_OPTIONS,
177         STREAM_SSL_LONG_OPTIONS,
178         TABLE_LONG_OPTIONS,
179         {NULL, 0, NULL, 0},
180     };
181     const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
182     char *tmp, *short_options;
183
184     struct option *options;
185     size_t allocated_options;
186     size_t n_options;
187     size_t i;
188
189     tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
190     short_options = xasprintf("+%s", tmp);
191     free(tmp);
192
193     /* We want to parse both global and command-specific options here, but
194      * getopt_long() isn't too convenient for the job.  We copy our global
195      * options into a dynamic array, then append all of the command-specific
196      * options. */
197     options = xmemdup(global_long_options, sizeof global_long_options);
198     allocated_options = ARRAY_SIZE(global_long_options);
199     n_options = n_global_long_options;
200     ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
201     table_style.format = TF_LIST;
202
203     for (;;) {
204         int idx;
205         int c;
206
207         c = getopt_long(argc, argv, short_options, options, &idx);
208         if (c == -1) {
209             break;
210         }
211
212         switch (c) {
213         case OPT_DB:
214             db = optarg;
215             break;
216
217         case OPT_ONELINE:
218             oneline = true;
219             break;
220
221         case OPT_NO_SYSLOG:
222             vlog_set_levels(&VLM_nbctl, VLF_SYSLOG, VLL_WARN);
223             break;
224
225         case OPT_DRY_RUN:
226             dry_run = true;
227             break;
228
229         case OPT_LOCAL:
230             if (shash_find(local_options, options[idx].name)) {
231                 ctl_fatal("'%s' option specified multiple times",
232                             options[idx].name);
233             }
234             shash_add_nocopy(local_options,
235                              xasprintf("--%s", options[idx].name),
236                              optarg ? xstrdup(optarg) : NULL);
237             break;
238
239         case 'h':
240             usage();
241             exit(EXIT_SUCCESS);
242
243         case OPT_COMMANDS:
244             ctl_print_commands();
245
246         case OPT_OPTIONS:
247             ctl_print_options(global_long_options);
248
249         case 'V':
250             ovs_print_version(0, 0);
251             printf("DB Schema %s\n", nbrec_get_db_version());
252             exit(EXIT_SUCCESS);
253
254         case 't':
255             timeout = strtoul(optarg, NULL, 10);
256             if (timeout < 0) {
257                 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
258             }
259             break;
260
261         VLOG_OPTION_HANDLERS
262         TABLE_OPTION_HANDLERS(&table_style)
263         STREAM_SSL_OPTION_HANDLERS
264
265         case '?':
266             exit(EXIT_FAILURE);
267
268         default:
269             abort();
270         }
271     }
272     free(short_options);
273
274     if (!db) {
275         db = nbctl_default_db();
276     }
277
278     for (i = n_global_long_options; options[i].name; i++) {
279         free(CONST_CAST(char *, options[i].name));
280     }
281     free(options);
282 }
283
284 static void
285 usage(void)
286 {
287     printf("\
288 %s: OVN northbound DB management utility\n\
289 usage: %s [OPTIONS] COMMAND [ARG...]\n\
290 \n\
291 General commands:\n\
292   show                      print overview of database contents\n\
293   show LSWITCH              print overview of database contents for LSWITCH\n\
294 \n\
295 Logical switch commands:\n\
296   lswitch-add [LSWITCH]     create a logical switch named LSWITCH\n\
297   lswitch-del LSWITCH       delete LSWITCH and all its ports\n\
298   lswitch-list              print the names of all logical switches\n\
299 \n\
300 ACL commands:\n\
301   acl-add LSWITCH DIRECTION PRIORITY MATCH ACTION [log]\n\
302                             add an ACL to LSWITCH\n\
303   acl-del LSWITCH [DIRECTION [PRIORITY MATCH]]\n\
304                             remove ACLs from LSWITCH\n\
305   acl-list LSWITCH          print ACLs for LSWITCH\n\
306 \n\
307 Logical port commands:\n\
308   lport-add LSWITCH LPORT   add logical port LPORT on LSWITCH\n\
309   lport-add LSWITCH LPORT PARENT TAG\n\
310                             add logical port LPORT on LSWITCH with PARENT\n\
311                             on TAG\n\
312   lport-del LPORT           delete LPORT from its attached switch\n\
313   lport-list LSWITCH        print the names of all logical ports on LSWITCH\n\
314   lport-get-parent LPORT    get the parent of LPORT if set\n\
315   lport-get-tag LPORT       get the LPORT's tag if set\n\
316   lport-set-addresses LPORT [ADDRESS]...\n\
317                             set MAC or MAC+IP addresses for LPORT.\n\
318   lport-get-addresses LPORT      get a list of MAC addresses on LPORT\n\
319   lport-set-port-security LPORT [ADDRS]...\n\
320                             set port security addresses for LPORT.\n\
321   lport-get-port-security LPORT    get LPORT's port security addresses\n\
322   lport-get-up LPORT        get state of LPORT ('up' or 'down')\n\
323   lport-set-enabled LPORT STATE\n\
324                             set administrative state LPORT\n\
325                             ('enabled' or 'disabled')\n\
326   lport-get-enabled LPORT   get administrative state LPORT\n\
327                             ('enabled' or 'disabled')\n\
328   lport-set-type LPORT TYPE Set the type for LPORT\n\
329   lport-get-type LPORT      Get the type for LPORT\n\
330   lport-set-options LPORT KEY=VALUE [KEY=VALUE]...\n\
331                             Set options related to the type of LPORT\n\
332   lport-get-options LPORT   Get the type specific options for LPORT\n\
333 \n\
334 %s\
335 \n\
336 Options:\n\
337   --db=DATABASE               connect to DATABASE\n\
338                               (default: %s)\n\
339   -t, --timeout=SECS          wait at most SECS seconds\n\
340   --dry-run                   do not commit changes to database\n\
341   --oneline                   print exactly one line of output per command\n",
342            program_name, program_name, ctl_get_db_cmd_usage(), nbctl_default_db());
343     vlog_usage();
344     printf("\
345   --no-syslog             equivalent to --verbose=nbctl:syslog:warn\n");
346     printf("\n\
347 Other options:\n\
348   -h, --help                  display this help message\n\
349   -V, --version               display version information\n");
350     exit(EXIT_SUCCESS);
351 }
352 \f
353 static const struct nbrec_logical_switch *
354 lswitch_by_name_or_uuid(struct ctl_context *ctx, const char *id)
355 {
356     const struct nbrec_logical_switch *lswitch = NULL;
357     bool is_uuid = false;
358     bool duplicate = false;
359     struct uuid lswitch_uuid;
360
361     if (uuid_from_string(&lswitch_uuid, id)) {
362         is_uuid = true;
363         lswitch = nbrec_logical_switch_get_for_uuid(ctx->idl,
364                                                     &lswitch_uuid);
365     }
366
367     if (!lswitch) {
368         const struct nbrec_logical_switch *iter;
369
370         NBREC_LOGICAL_SWITCH_FOR_EACH(iter, ctx->idl) {
371             if (strcmp(iter->name, id)) {
372                 continue;
373             }
374             if (lswitch) {
375                 VLOG_WARN("There is more than one logical switch named '%s'. "
376                         "Use a UUID.", id);
377                 lswitch = NULL;
378                 duplicate = true;
379                 break;
380             }
381             lswitch = iter;
382         }
383     }
384
385     if (!lswitch && !duplicate) {
386         VLOG_WARN("lswitch not found for %s: '%s'",
387                 is_uuid ? "UUID" : "name", id);
388     }
389
390     return lswitch;
391 }
392
393 static void
394 print_lswitch(const struct nbrec_logical_switch *lswitch, struct ds *s)
395 {
396     ds_put_format(s, "    lswitch "UUID_FMT" (%s)\n",
397                   UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
398
399     for (size_t i = 0; i < lswitch->n_ports; i++) {
400         const struct nbrec_logical_port *lport = lswitch->ports[i];
401
402         ds_put_format(s, "        lport %s\n", lport->name);
403         if (lport->parent_name) {
404             ds_put_format(s, "            parent: %s\n", lport->parent_name);
405         }
406         if (lport->n_tag) {
407             ds_put_format(s, "            tag: %"PRIu64"\n", lport->tag[0]);
408         }
409         if (lport->n_addresses) {
410             ds_put_cstr(s, "            addresses: [");
411             for (size_t j = 0; j < lport->n_addresses; j++) {
412                 ds_put_format(s, "%s\"%s\"",
413                         j == 0 ? "" : ", ",
414                         lport->addresses[j]);
415             }
416             ds_put_cstr(s, "]\n");
417         }
418     }
419 }
420
421 static void
422 nbctl_show(struct ctl_context *ctx)
423 {
424     const struct nbrec_logical_switch *lswitch;
425
426     if (ctx->argc == 2) {
427         lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1]);
428         if (lswitch) {
429             print_lswitch(lswitch, &ctx->output);
430         }
431     } else {
432         NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, ctx->idl) {
433             print_lswitch(lswitch, &ctx->output);
434         }
435     }
436 }
437
438 static void
439 nbctl_lswitch_add(struct ctl_context *ctx)
440 {
441     struct nbrec_logical_switch *lswitch;
442
443     lswitch = nbrec_logical_switch_insert(ctx->txn);
444     if (ctx->argc == 2) {
445         nbrec_logical_switch_set_name(lswitch, ctx->argv[1]);
446     }
447 }
448
449 static void
450 nbctl_lswitch_del(struct ctl_context *ctx)
451 {
452     const char *id = ctx->argv[1];
453     const struct nbrec_logical_switch *lswitch;
454
455     lswitch = lswitch_by_name_or_uuid(ctx, id);
456     if (!lswitch) {
457         return;
458     }
459
460     nbrec_logical_switch_delete(lswitch);
461 }
462
463 static void
464 nbctl_lswitch_list(struct ctl_context *ctx)
465 {
466     const struct nbrec_logical_switch *lswitch;
467     struct smap lswitches;
468
469     smap_init(&lswitches);
470     NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, ctx->idl) {
471         smap_add_format(&lswitches, lswitch->name, UUID_FMT " (%s)",
472                         UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
473     }
474     const struct smap_node **nodes = smap_sort(&lswitches);
475     for (size_t i = 0; i < smap_count(&lswitches); i++) {
476         const struct smap_node *node = nodes[i];
477         ds_put_format(&ctx->output, "%s\n", node->value);
478     }
479     smap_destroy(&lswitches);
480     free(nodes);
481 }
482 \f
483 static const struct nbrec_logical_port *
484 lport_by_name_or_uuid(struct ctl_context *ctx, const char *id)
485 {
486     const struct nbrec_logical_port *lport = NULL;
487     bool is_uuid = false;
488     struct uuid lport_uuid;
489
490     if (uuid_from_string(&lport_uuid, id)) {
491         is_uuid = true;
492         lport = nbrec_logical_port_get_for_uuid(ctx->idl, &lport_uuid);
493     }
494
495     if (!lport) {
496         NBREC_LOGICAL_PORT_FOR_EACH(lport, ctx->idl) {
497             if (!strcmp(lport->name, id)) {
498                 break;
499             }
500         }
501     }
502
503     if (!lport) {
504         VLOG_WARN("lport not found for %s: '%s'",
505                 is_uuid ? "UUID" : "name", id);
506     }
507
508     return lport;
509 }
510
511 static void
512 nbctl_lport_add(struct ctl_context *ctx)
513 {
514     struct nbrec_logical_port *lport;
515     const struct nbrec_logical_switch *lswitch;
516     int64_t tag;
517
518     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1]);
519     if (!lswitch) {
520         return;
521     }
522
523     if (ctx->argc != 3 && ctx->argc != 5) {
524         /* If a parent_name is specified, a tag must be specified as well. */
525         VLOG_WARN("Invalid arguments to lport-add.");
526         return;
527     }
528
529     if (ctx->argc == 5) {
530         /* Validate tag. */
531         if (!ovs_scan(ctx->argv[4], "%"SCNd64, &tag) || tag < 0 || tag > 4095) {
532             VLOG_WARN("Invalid tag '%s'", ctx->argv[4]);
533             return;
534         }
535     }
536
537     /* Create the logical port. */
538     lport = nbrec_logical_port_insert(ctx->txn);
539     nbrec_logical_port_set_name(lport, ctx->argv[2]);
540     if (ctx->argc == 5) {
541         nbrec_logical_port_set_parent_name(lport, ctx->argv[3]);
542         nbrec_logical_port_set_tag(lport, &tag, 1);
543     }
544
545     /* Insert the logical port into the logical switch. */
546     nbrec_logical_switch_verify_ports(lswitch);
547     struct nbrec_logical_port **new_ports = xmalloc(sizeof *new_ports *
548                                                     (lswitch->n_ports + 1));
549     memcpy(new_ports, lswitch->ports, sizeof *new_ports * lswitch->n_ports);
550     new_ports[lswitch->n_ports] = lport;
551     nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports + 1);
552     free(new_ports);
553 }
554
555 /* Removes lport 'lswitch->ports[idx]'. */
556 static void
557 remove_lport(const struct nbrec_logical_switch *lswitch, size_t idx)
558 {
559     const struct nbrec_logical_port *lport = lswitch->ports[idx];
560
561     /* First remove 'lport' from the array of ports.  This is what will
562      * actually cause the logical port to be deleted when the transaction is
563      * sent to the database server (due to garbage collection). */
564     struct nbrec_logical_port **new_ports
565         = xmemdup(lswitch->ports, sizeof *new_ports * lswitch->n_ports);
566     new_ports[idx] = new_ports[lswitch->n_ports - 1];
567     nbrec_logical_switch_verify_ports(lswitch);
568     nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports - 1);
569     free(new_ports);
570
571     /* Delete 'lport' from the IDL.  This won't have a real effect on the
572      * database server (the IDL will suppress it in fact) but it means that it
573      * won't show up when we iterate with NBREC_LOGICAL_PORT_FOR_EACH later. */
574     nbrec_logical_port_delete(lport);
575 }
576
577 static void
578 nbctl_lport_del(struct ctl_context *ctx)
579 {
580     const struct nbrec_logical_port *lport;
581
582     lport = lport_by_name_or_uuid(ctx, ctx->argv[1]);
583     if (!lport) {
584         return;
585     }
586
587     /* Find the switch that contains 'lport', then delete it. */
588     const struct nbrec_logical_switch *lswitch;
589     NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, ctx->idl) {
590         for (size_t i = 0; i < lswitch->n_ports; i++) {
591             if (lswitch->ports[i] == lport) {
592                 remove_lport(lswitch, i);
593                 return;
594             }
595         }
596     }
597
598     VLOG_WARN("logical port %s is not part of any logical switch",
599               ctx->argv[1]);
600 }
601
602 static void
603 nbctl_lport_list(struct ctl_context *ctx)
604 {
605     const char *id = ctx->argv[1];
606     const struct nbrec_logical_switch *lswitch;
607     struct smap lports;
608     size_t i;
609
610     lswitch = lswitch_by_name_or_uuid(ctx, id);
611     if (!lswitch) {
612         return;
613     }
614
615     smap_init(&lports);
616     for (i = 0; i < lswitch->n_ports; i++) {
617         const struct nbrec_logical_port *lport = lswitch->ports[i];
618         smap_add_format(&lports, lport->name, UUID_FMT " (%s)",
619                         UUID_ARGS(&lport->header_.uuid), lport->name);
620     }
621     const struct smap_node **nodes = smap_sort(&lports);
622     for (i = 0; i < smap_count(&lports); i++) {
623         const struct smap_node *node = nodes[i];
624         ds_put_format(&ctx->output, "%s\n", node->value);
625     }
626     smap_destroy(&lports);
627     free(nodes);
628 }
629
630 static void
631 nbctl_lport_get_parent(struct ctl_context *ctx)
632 {
633     const struct nbrec_logical_port *lport;
634
635     lport = lport_by_name_or_uuid(ctx, ctx->argv[1]);
636     if (!lport) {
637         return;
638     }
639
640     if (lport->parent_name) {
641         ds_put_format(&ctx->output, "%s\n", lport->parent_name);
642     }
643 }
644
645 static void
646 nbctl_lport_get_tag(struct ctl_context *ctx)
647 {
648     const struct nbrec_logical_port *lport;
649
650     lport = lport_by_name_or_uuid(ctx, ctx->argv[1]);
651     if (!lport) {
652         return;
653     }
654
655     if (lport->n_tag > 0) {
656         ds_put_format(&ctx->output, "%"PRId64"\n", lport->tag[0]);
657     }
658 }
659
660 static void
661 nbctl_lport_set_addresses(struct ctl_context *ctx)
662 {
663     const char *id = ctx->argv[1];
664     const struct nbrec_logical_port *lport;
665
666     lport = lport_by_name_or_uuid(ctx, id);
667     if (!lport) {
668         return;
669     }
670
671     int i;
672     for (i = 2; i < ctx->argc; i++) {
673         struct eth_addr ea;
674
675         if (strcmp(ctx->argv[i], "unknown")
676             && !ovs_scan(ctx->argv[i], ETH_ADDR_SCAN_FMT,
677                          ETH_ADDR_SCAN_ARGS(ea))) {
678             VLOG_ERR("Invalid address format (%s). See ovn-nb(5). "
679                      "Hint: An Ethernet address must be "
680                      "listed before an IP address, together as a single "
681                      "argument.", ctx->argv[i]);
682             return;
683         }
684     }
685
686     nbrec_logical_port_set_addresses(lport,
687             (const char **) ctx->argv + 2, ctx->argc - 2);
688 }
689
690 static void
691 nbctl_lport_get_addresses(struct ctl_context *ctx)
692 {
693     const char *id = ctx->argv[1];
694     const struct nbrec_logical_port *lport;
695     struct svec addresses;
696     const char *mac;
697     size_t i;
698
699     lport = lport_by_name_or_uuid(ctx, id);
700     if (!lport) {
701         return;
702     }
703
704     svec_init(&addresses);
705     for (i = 0; i < lport->n_addresses; i++) {
706         svec_add(&addresses, lport->addresses[i]);
707     }
708     svec_sort(&addresses);
709     SVEC_FOR_EACH(i, mac, &addresses) {
710         ds_put_format(&ctx->output, "%s\n", mac);
711     }
712     svec_destroy(&addresses);
713 }
714
715 static void
716 nbctl_lport_set_port_security(struct ctl_context *ctx)
717 {
718     const char *id = ctx->argv[1];
719     const struct nbrec_logical_port *lport;
720
721     lport = lport_by_name_or_uuid(ctx, id);
722     if (!lport) {
723         return;
724     }
725
726     nbrec_logical_port_set_port_security(lport,
727             (const char **) ctx->argv + 2, ctx->argc - 2);
728 }
729
730 static void
731 nbctl_lport_get_port_security(struct ctl_context *ctx)
732 {
733     const char *id = ctx->argv[1];
734     const struct nbrec_logical_port *lport;
735     struct svec addrs;
736     const char *addr;
737     size_t i;
738
739     lport = lport_by_name_or_uuid(ctx, id);
740     if (!lport) {
741         return;
742     }
743
744     svec_init(&addrs);
745     for (i = 0; i < lport->n_port_security; i++) {
746         svec_add(&addrs, lport->port_security[i]);
747     }
748     svec_sort(&addrs);
749     SVEC_FOR_EACH(i, addr, &addrs) {
750         ds_put_format(&ctx->output, "%s\n", addr);
751     }
752     svec_destroy(&addrs);
753 }
754
755 static void
756 nbctl_lport_get_up(struct ctl_context *ctx)
757 {
758     const char *id = ctx->argv[1];
759     const struct nbrec_logical_port *lport;
760
761     lport = lport_by_name_or_uuid(ctx, id);
762     if (!lport) {
763         return;
764     }
765
766     ds_put_format(&ctx->output,
767                   "%s\n", (lport->up && *lport->up) ? "up" : "down");
768 }
769
770 static void
771 nbctl_lport_set_enabled(struct ctl_context *ctx)
772 {
773     const char *id = ctx->argv[1];
774     const char *state = ctx->argv[2];
775     const struct nbrec_logical_port *lport;
776
777     lport = lport_by_name_or_uuid(ctx, id);
778     if (!lport) {
779         return;
780     }
781
782     if (!strcasecmp(state, "enabled")) {
783         bool enabled = true;
784         nbrec_logical_port_set_enabled(lport, &enabled, 1);
785     } else if (!strcasecmp(state, "disabled")) {
786         bool enabled = false;
787         nbrec_logical_port_set_enabled(lport, &enabled, 1);
788     } else {
789         VLOG_ERR("Invalid state '%s' provided to lport-set-enabled", state);
790     }
791 }
792
793 static void
794 nbctl_lport_get_enabled(struct ctl_context *ctx)
795 {
796     const char *id = ctx->argv[1];
797     const struct nbrec_logical_port *lport;
798
799     lport = lport_by_name_or_uuid(ctx, id);
800     if (!lport) {
801         return;
802     }
803
804     ds_put_format(&ctx->output, "%s\n",
805                   !lport->enabled || *lport->enabled ? "enabled" : "disabled");
806 }
807
808 static void
809 nbctl_lport_set_type(struct ctl_context *ctx)
810 {
811     const char *id = ctx->argv[1];
812     const char *type = ctx->argv[2];
813     const struct nbrec_logical_port *lport;
814
815     lport = lport_by_name_or_uuid(ctx, id);
816     if (!lport) {
817         return;
818     }
819
820     nbrec_logical_port_set_type(lport, type);
821 }
822
823 static void
824 nbctl_lport_get_type(struct ctl_context *ctx)
825 {
826     const char *id = ctx->argv[1];
827     const struct nbrec_logical_port *lport;
828
829     lport = lport_by_name_or_uuid(ctx, id);
830     if (!lport) {
831         return;
832     }
833
834     ds_put_format(&ctx->output, "%s\n", lport->type);
835 }
836
837 static void
838 nbctl_lport_set_options(struct ctl_context *ctx)
839 {
840     const char *id = ctx->argv[1];
841     const struct nbrec_logical_port *lport;
842     size_t i;
843     struct smap options = SMAP_INITIALIZER(&options);
844
845     lport = lport_by_name_or_uuid(ctx, id);
846     if (!lport) {
847         return;
848     }
849
850     for (i = 2; i < ctx->argc; i++) {
851         char *key, *value;
852         value = xstrdup(ctx->argv[i]);
853         key = strsep(&value, "=");
854         if (value) {
855             smap_add(&options, key, value);
856         }
857         free(key);
858     }
859
860     nbrec_logical_port_set_options(lport, &options);
861
862     smap_destroy(&options);
863 }
864
865 static void
866 nbctl_lport_get_options(struct ctl_context *ctx)
867 {
868     const char *id = ctx->argv[1];
869     const struct nbrec_logical_port *lport;
870     struct smap_node *node;
871
872     lport = lport_by_name_or_uuid(ctx, id);
873     if (!lport) {
874         return;
875     }
876
877     SMAP_FOR_EACH(node, &lport->options) {
878         ds_put_format(&ctx->output, "%s=%s\n", node->key, node->value);
879     }
880 }
881
882 enum {
883     DIR_FROM_LPORT,
884     DIR_TO_LPORT
885 };
886
887 static int
888 dir_encode(const char *dir)
889 {
890     if (!strcmp(dir, "from-lport")) {
891         return DIR_FROM_LPORT;
892     } else if (!strcmp(dir, "to-lport")) {
893         return DIR_TO_LPORT;
894     }
895
896     OVS_NOT_REACHED();
897 }
898
899 static int
900 acl_cmp(const void *acl1_, const void *acl2_)
901 {
902     const struct nbrec_acl *const *acl1p = acl1_;
903     const struct nbrec_acl *const *acl2p = acl2_;
904     const struct nbrec_acl *acl1 = *acl1p;
905     const struct nbrec_acl *acl2 = *acl2p;
906
907     int dir1 = dir_encode(acl1->direction);
908     int dir2 = dir_encode(acl2->direction);
909
910     if (dir1 != dir2) {
911         return dir1 < dir2 ? -1 : 1;
912     } else if (acl1->priority != acl2->priority) {
913         return acl1->priority > acl2->priority ? -1 : 1;
914     } else {
915         return strcmp(acl1->match, acl2->match);
916     }
917 }
918
919 static void
920 nbctl_acl_list(struct ctl_context *ctx)
921 {
922     const struct nbrec_logical_switch *lswitch;
923     const struct nbrec_acl **acls;
924     size_t i;
925
926     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1]);
927     if (!lswitch) {
928         return;
929     }
930
931     acls = xmalloc(sizeof *acls * lswitch->n_acls);
932     for (i = 0; i < lswitch->n_acls; i++) {
933         acls[i] = lswitch->acls[i];
934     }
935
936     qsort(acls, lswitch->n_acls, sizeof *acls, acl_cmp);
937
938     for (i = 0; i < lswitch->n_acls; i++) {
939         const struct nbrec_acl *acl = acls[i];
940         printf("%10s %5"PRId64" (%s) %s%s\n", acl->direction, acl->priority,
941                 acl->match, acl->action, acl->log ? " log" : "");
942     }
943
944     free(acls);
945 }
946
947 static void
948 nbctl_acl_add(struct ctl_context *ctx)
949 {
950     const struct nbrec_logical_switch *lswitch;
951     const char *action = ctx->argv[5];
952     const char *direction;
953     int64_t priority;
954
955     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1]);
956     if (!lswitch) {
957         return;
958     }
959
960     /* Validate direction.  Only require the first letter. */
961     if (ctx->argv[2][0] == 't') {
962         direction = "to-lport";
963     } else if (ctx->argv[2][0] == 'f') {
964         direction = "from-lport";
965     } else {
966         VLOG_WARN("Invalid direction '%s'", ctx->argv[2]);
967         return;
968     }
969
970     /* Validate priority. */
971     if (!ovs_scan(ctx->argv[3], "%"SCNd64, &priority) || priority < 0
972         || priority > 32767) {
973         VLOG_WARN("Invalid priority '%s'", ctx->argv[3]);
974         return;
975     }
976
977     /* Validate action. */
978     if (strcmp(action, "allow") && strcmp(action, "allow-related")
979         && strcmp(action, "drop") && strcmp(action, "reject")) {
980         VLOG_WARN("Invalid action '%s'", action);
981         return;
982     }
983
984     /* Create the acl. */
985     struct nbrec_acl *acl = nbrec_acl_insert(ctx->txn);
986     nbrec_acl_set_priority(acl, priority);
987     nbrec_acl_set_direction(acl, direction);
988     nbrec_acl_set_match(acl, ctx->argv[4]);
989     nbrec_acl_set_action(acl, action);
990     if (shash_find(&ctx->options, "--log") != NULL) {
991         nbrec_acl_set_log(acl, true);
992     }
993
994     /* Insert the acl into the logical switch. */
995     nbrec_logical_switch_verify_acls(lswitch);
996     struct nbrec_acl **new_acls = xmalloc(sizeof *new_acls *
997                                           (lswitch->n_acls + 1));
998     memcpy(new_acls, lswitch->acls, sizeof *new_acls * lswitch->n_acls);
999     new_acls[lswitch->n_acls] = acl;
1000     nbrec_logical_switch_set_acls(lswitch, new_acls, lswitch->n_acls + 1);
1001     free(new_acls);
1002 }
1003
1004 static void
1005 nbctl_acl_del(struct ctl_context *ctx)
1006 {
1007     const struct nbrec_logical_switch *lswitch;
1008     const char *direction;
1009     int64_t priority = 0;
1010
1011     lswitch = lswitch_by_name_or_uuid(ctx, ctx->argv[1]);
1012     if (!lswitch) {
1013         return;
1014     }
1015
1016     if (ctx->argc != 2 && ctx->argc != 3 && ctx->argc != 5) {
1017         VLOG_WARN("Invalid number of arguments");
1018         return;
1019     }
1020
1021     if (ctx->argc == 2) {
1022         /* If direction, priority, and match are not specified, delete
1023          * all ACLs. */
1024         nbrec_logical_switch_verify_acls(lswitch);
1025         nbrec_logical_switch_set_acls(lswitch, NULL, 0);
1026         return;
1027     }
1028
1029     /* Validate direction.  Only require first letter. */
1030     if (ctx->argv[2][0] == 't') {
1031         direction = "to-lport";
1032     } else if (ctx->argv[2][0] == 'f') {
1033         direction = "from-lport";
1034     } else {
1035         VLOG_WARN("Invalid direction '%s'", ctx->argv[2]);
1036         return;
1037     }
1038
1039     /* If priority and match are not specified, delete all ACLs with the
1040      * specified direction. */
1041     if (ctx->argc == 3) {
1042         struct nbrec_acl **new_acls
1043             = xmalloc(sizeof *new_acls * lswitch->n_acls);
1044
1045         int n_acls = 0;
1046         for (size_t i = 0; i < lswitch->n_acls; i++) {
1047             if (strcmp(direction, lswitch->acls[i]->direction)) {
1048                 new_acls[n_acls++] = lswitch->acls[i];
1049             }
1050         }
1051
1052         nbrec_logical_switch_verify_acls(lswitch);
1053         nbrec_logical_switch_set_acls(lswitch, new_acls, n_acls);
1054         free(new_acls);
1055         return;
1056     }
1057
1058     /* Validate priority. */
1059     if (!ovs_scan(ctx->argv[3], "%"SCNd64, &priority) || priority < 0
1060         || priority > 32767) {
1061         VLOG_WARN("Invalid priority '%s'", ctx->argv[3]);
1062         return;
1063     }
1064
1065     /* Remove the matching rule. */
1066     for (size_t i = 0; i < lswitch->n_acls; i++) {
1067         struct nbrec_acl *acl = lswitch->acls[i];
1068
1069         if (priority == acl->priority && !strcmp(ctx->argv[4], acl->match) &&
1070              !strcmp(direction, acl->direction)) {
1071             struct nbrec_acl **new_acls
1072                 = xmemdup(lswitch->acls, sizeof *new_acls * lswitch->n_acls);
1073             new_acls[i] = lswitch->acls[lswitch->n_acls - 1];
1074             nbrec_logical_switch_verify_acls(lswitch);
1075             nbrec_logical_switch_set_acls(lswitch, new_acls,
1076                                           lswitch->n_acls - 1);
1077             free(new_acls);
1078             return;
1079         }
1080     }
1081 }
1082 \f
1083 static const struct ctl_table_class tables[] = {
1084     {&nbrec_table_logical_switch,
1085      {{&nbrec_table_logical_switch, &nbrec_logical_switch_col_name, NULL},
1086       {NULL, NULL, NULL}}},
1087
1088     {&nbrec_table_logical_port,
1089      {{&nbrec_table_logical_port, &nbrec_logical_port_col_name, NULL},
1090       {NULL, NULL, NULL}}},
1091
1092     {&nbrec_table_acl,
1093      {{NULL, NULL, NULL},
1094       {NULL, NULL, NULL}}},
1095
1096     {&nbrec_table_logical_router,
1097      {{&nbrec_table_logical_router, &nbrec_logical_router_col_name, NULL},
1098       {NULL, NULL, NULL}}},
1099
1100     {&nbrec_table_logical_router_port,
1101      {{&nbrec_table_logical_router_port, &nbrec_logical_router_port_col_name,
1102        NULL},
1103       {NULL, NULL, NULL}}},
1104
1105     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
1106 };
1107 \f
1108 static void
1109 run_prerequisites(struct ctl_command *commands, size_t n_commands,
1110                   struct ovsdb_idl *idl)
1111 {
1112     struct ctl_command *c;
1113
1114     for (c = commands; c < &commands[n_commands]; c++) {
1115         if (c->syntax->prerequisites) {
1116             struct ctl_context ctx;
1117
1118             ds_init(&c->output);
1119             c->table = NULL;
1120
1121             ctl_context_init(&ctx, c, idl, NULL, NULL, NULL);
1122             (c->syntax->prerequisites)(&ctx);
1123             ctl_context_done(&ctx, c);
1124
1125             ovs_assert(!c->output.string);
1126             ovs_assert(!c->table);
1127         }
1128     }
1129 }
1130
1131 static void
1132 do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
1133          struct ovsdb_idl *idl)
1134 {
1135     struct ovsdb_idl_txn *txn;
1136     enum ovsdb_idl_txn_status status;
1137     struct ovsdb_symbol_table *symtab;
1138     struct ctl_context ctx;
1139     struct ctl_command *c;
1140     struct shash_node *node;
1141     char *error = NULL;
1142
1143     txn = the_idl_txn = ovsdb_idl_txn_create(idl);
1144     if (dry_run) {
1145         ovsdb_idl_txn_set_dry_run(txn);
1146     }
1147
1148     ovsdb_idl_txn_add_comment(txn, "ovs-nbctl: %s", args);
1149
1150     symtab = ovsdb_symbol_table_create();
1151     for (c = commands; c < &commands[n_commands]; c++) {
1152         ds_init(&c->output);
1153         c->table = NULL;
1154     }
1155     ctl_context_init(&ctx, NULL, idl, txn, symtab, NULL);
1156     for (c = commands; c < &commands[n_commands]; c++) {
1157         ctl_context_init_command(&ctx, c);
1158         if (c->syntax->run) {
1159             (c->syntax->run)(&ctx);
1160         }
1161         ctl_context_done_command(&ctx, c);
1162
1163         if (ctx.try_again) {
1164             ctl_context_done(&ctx, NULL);
1165             goto try_again;
1166         }
1167     }
1168     ctl_context_done(&ctx, NULL);
1169
1170     SHASH_FOR_EACH (node, &symtab->sh) {
1171         struct ovsdb_symbol *symbol = node->data;
1172         if (!symbol->created) {
1173             ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
1174                       "with \"-- --id=%s create ...\")",
1175                       node->name, node->name);
1176         }
1177         if (!symbol->strong_ref) {
1178             if (!symbol->weak_ref) {
1179                 VLOG_WARN("row id \"%s\" was created but no reference to it "
1180                           "was inserted, so it will not actually appear in "
1181                           "the database", node->name);
1182             } else {
1183                 VLOG_WARN("row id \"%s\" was created but only a weak "
1184                           "reference to it was inserted, so it will not "
1185                           "actually appear in the database", node->name);
1186             }
1187         }
1188     }
1189
1190     status = ovsdb_idl_txn_commit_block(txn);
1191     if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
1192         for (c = commands; c < &commands[n_commands]; c++) {
1193             if (c->syntax->postprocess) {
1194                 ctl_context_init(&ctx, c, idl, txn, symtab, NULL);
1195                 (c->syntax->postprocess)(&ctx);
1196                 ctl_context_done(&ctx, c);
1197             }
1198         }
1199     }
1200     error = xstrdup(ovsdb_idl_txn_get_error(txn));
1201
1202     switch (status) {
1203     case TXN_UNCOMMITTED:
1204     case TXN_INCOMPLETE:
1205         OVS_NOT_REACHED();
1206
1207     case TXN_ABORTED:
1208         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1209         ctl_fatal("transaction aborted");
1210
1211     case TXN_UNCHANGED:
1212     case TXN_SUCCESS:
1213         break;
1214
1215     case TXN_TRY_AGAIN:
1216         goto try_again;
1217
1218     case TXN_ERROR:
1219         ctl_fatal("transaction error: %s", error);
1220
1221     case TXN_NOT_LOCKED:
1222         /* Should not happen--we never call ovsdb_idl_set_lock(). */
1223         ctl_fatal("database not locked");
1224
1225     default:
1226         OVS_NOT_REACHED();
1227     }
1228     free(error);
1229
1230     ovsdb_symbol_table_destroy(symtab);
1231
1232     for (c = commands; c < &commands[n_commands]; c++) {
1233         struct ds *ds = &c->output;
1234
1235         if (c->table) {
1236             table_print(c->table, &table_style);
1237         } else if (oneline) {
1238             size_t j;
1239
1240             ds_chomp(ds, '\n');
1241             for (j = 0; j < ds->length; j++) {
1242                 int ch = ds->string[j];
1243                 switch (ch) {
1244                 case '\n':
1245                     fputs("\\n", stdout);
1246                     break;
1247
1248                 case '\\':
1249                     fputs("\\\\", stdout);
1250                     break;
1251
1252                 default:
1253                     putchar(ch);
1254                 }
1255             }
1256             putchar('\n');
1257         } else {
1258             fputs(ds_cstr(ds), stdout);
1259         }
1260         ds_destroy(&c->output);
1261         table_destroy(c->table);
1262         free(c->table);
1263
1264         shash_destroy_free_data(&c->options);
1265     }
1266     free(commands);
1267     ovsdb_idl_txn_destroy(txn);
1268     ovsdb_idl_destroy(idl);
1269
1270     exit(EXIT_SUCCESS);
1271
1272 try_again:
1273     /* Our transaction needs to be rerun, or a prerequisite was not met.  Free
1274      * resources and return so that the caller can try again. */
1275     if (txn) {
1276         ovsdb_idl_txn_abort(txn);
1277         ovsdb_idl_txn_destroy(txn);
1278         the_idl_txn = NULL;
1279     }
1280     ovsdb_symbol_table_destroy(symtab);
1281     for (c = commands; c < &commands[n_commands]; c++) {
1282         ds_destroy(&c->output);
1283         table_destroy(c->table);
1284         free(c->table);
1285     }
1286     free(error);
1287 }
1288
1289 /* Frees the current transaction and the underlying IDL and then calls
1290  * exit(status).
1291  *
1292  * Freeing the transaction and the IDL is not strictly necessary, but it makes
1293  * for a clean memory leak report from valgrind in the normal case.  That makes
1294  * it easier to notice real memory leaks. */
1295 static void
1296 nbctl_exit(int status)
1297 {
1298     if (the_idl_txn) {
1299         ovsdb_idl_txn_abort(the_idl_txn);
1300         ovsdb_idl_txn_destroy(the_idl_txn);
1301     }
1302     ovsdb_idl_destroy(the_idl);
1303     exit(status);
1304 }
1305
1306 static const struct ctl_command_syntax nbctl_commands[] = {
1307     { "show", 0, 1, "[LSWITCH]", NULL, nbctl_show, NULL, "", RO },
1308
1309     /* lswitch commands. */
1310     { "lswitch-add", 0, 1, "[LSWITCH]", NULL, nbctl_lswitch_add,
1311       NULL, "", RW },
1312     { "lswitch-del", 1, 1, "LSWITCH", NULL, nbctl_lswitch_del,
1313       NULL, "", RW },
1314     { "lswitch-list", 0, 0, "", NULL, nbctl_lswitch_list, NULL, "", RO },
1315
1316     /* acl commands. */
1317     { "acl-add", 5, 5, "LSWITCH DIRECTION PRIORITY MATCH ACTION", NULL,
1318       nbctl_acl_add, NULL, "--log", RW },
1319     { "acl-del", 1, 4, "LSWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
1320       nbctl_acl_del, NULL, "", RW },
1321     { "acl-list", 1, 1, "LSWITCH", NULL, nbctl_acl_list, NULL, "", RO },
1322
1323     /* lport commands. */
1324     { "lport-add", 2, 4, "LSWITCH LPORT [PARENT] [TAG]", NULL, nbctl_lport_add,
1325       NULL, "", RW },
1326     { "lport-del", 1, 1, "LPORT", NULL, nbctl_lport_del, NULL, "", RO },
1327     { "lport-list", 1, 1, "LSWITCH", NULL, nbctl_lport_list, NULL, "", RO },
1328     { "lport-get-parent", 1, 1, "LPORT", NULL, nbctl_lport_get_parent, NULL,
1329       "", RO },
1330     { "lport-get-tag", 1, 1, "LPORT", NULL, nbctl_lport_get_tag, NULL, "",
1331       RO },
1332     { "lport-set-addresses", 1, INT_MAX, "LPORT [ADDRESS]...", NULL,
1333       nbctl_lport_set_addresses, NULL, "", RW },
1334     { "lport-get-addresses", 1, 1, "LPORT", NULL,
1335       nbctl_lport_get_addresses, NULL,
1336       "", RO },
1337     { "lport-set-port-security", 0, INT_MAX, "LPORT [ADDRS]...", NULL,
1338       nbctl_lport_set_port_security, NULL, "", RW },
1339     { "lport-get-port-security", 1, 1, "LPORT", NULL,
1340       nbctl_lport_get_port_security, NULL, "", RO },
1341     { "lport-get-up", 1, 1, "LPORT", NULL, nbctl_lport_get_up, NULL, "", RO },
1342     { "lport-set-enabled", 2, 2, "LPORT STATE", NULL, nbctl_lport_set_enabled,
1343       NULL, "", RW },
1344     { "lport-get-enabled", 1, 1, "LPORT", NULL, nbctl_lport_get_enabled, NULL,
1345       "", RO },
1346     { "lport-set-type", 2, 2, "LPORT TYPE", NULL, nbctl_lport_set_type, NULL,
1347       "", RW },
1348     { "lport-get-type", 1, 1, "LPORT", NULL, nbctl_lport_get_type, NULL, "",
1349       RO },
1350     { "lport-set-options", 1, INT_MAX, "LPORT KEY=VALUE [KEY=VALUE]...", NULL,
1351       nbctl_lport_set_options, NULL, "", RW },
1352     { "lport-get-options", 1, 1, "LPORT", NULL, nbctl_lport_get_options, NULL,
1353       "", RO },
1354
1355     {NULL, 0, 0, NULL, NULL, NULL, NULL, "", RO},
1356 };
1357
1358 /* Registers nbctl and common db commands. */
1359 static void
1360 nbctl_cmd_init(void)
1361 {
1362     ctl_init(tables, NULL, nbctl_exit);
1363     ctl_register_commands(nbctl_commands);
1364 }