2 * Copyright (c) 2009, 2010, 2011, 2012, 2014, 2015 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
30 #include "db-ctl-base.h"
32 #include "command-line.h"
34 #include "dynamic-string.h"
35 #include "fatal-signal.h"
38 #include "ovsdb-data.h"
39 #include "ovsdb-idl.h"
40 #include "poll-loop.h"
43 #include "stream-ssl.h"
47 #include "vtep/vtep-idl.h"
51 #include "openvswitch/vconn.h"
52 #include "openvswitch/vlog.h"
54 VLOG_DEFINE_THIS_MODULE(vtep_ctl
);
56 struct vtep_ctl_context
;
58 /* --db: The database server to contact. */
59 static const char *db
;
61 /* --oneline: Write each command's output as a single line? */
64 /* --dry-run: Do not commit any changes. */
67 /* --timeout: Time to wait for a connection to 'db'. */
70 /* Format for table output. */
71 static struct table_style table_style
= TABLE_STYLE_DEFAULT
;
73 /* The IDL we're using and the current transaction, if any.
74 * This is for use by vtep_ctl_exit() only, to allow it to clean up.
75 * Other code should use its context arguments. */
76 static struct ovsdb_idl
*the_idl
;
77 static struct ovsdb_idl_txn
*the_idl_txn
;
79 OVS_NO_RETURN
static void vtep_ctl_exit(int status
);
80 static void vtep_ctl_cmd_init(void);
81 OVS_NO_RETURN
static void usage(void);
82 static void parse_options(int argc
, char *argv
[], struct shash
*local_options
);
83 static void run_prerequisites(struct ctl_command
[], size_t n_commands
,
85 static void do_vtep_ctl(const char *args
, struct ctl_command
*, size_t n
,
87 static struct vtep_ctl_lswitch
*find_lswitch(struct vtep_ctl_context
*,
92 main(int argc
, char *argv
[])
94 extern struct vlog_module VLM_reconnect
;
95 struct ovsdb_idl
*idl
;
96 struct ctl_command
*commands
;
97 struct shash local_options
;
102 set_program_name(argv
[0]);
103 fatal_ignore_sigpipe();
104 vlog_set_levels(NULL
, VLF_CONSOLE
, VLL_WARN
);
105 vlog_set_levels(&VLM_reconnect
, VLF_ANY_DESTINATION
, VLL_WARN
);
110 /* Log our arguments. This is often valuable for debugging systems. */
111 args
= process_escape_args(argv
);
112 VLOG(ctl_might_write_to_db(argv
) ? VLL_INFO
: VLL_DBG
, "Called as %s", args
);
114 /* Parse command line. */
115 shash_init(&local_options
);
116 parse_options(argc
, argv
, &local_options
);
117 commands
= ctl_parse_commands(argc
- optind
, argv
+ optind
, &local_options
,
124 /* Initialize IDL. */
125 idl
= the_idl
= ovsdb_idl_create(db
, &vteprec_idl_class
, false, false);
126 run_prerequisites(commands
, n_commands
, idl
);
128 /* Execute the commands.
130 * 'seqno' is the database sequence number for which we last tried to
131 * execute our transaction. There's no point in trying to commit more than
132 * once for any given sequence number, because if the transaction fails
133 * it's because the database changed and we need to obtain an up-to-date
134 * view of the database before we try the transaction again. */
135 seqno
= ovsdb_idl_get_seqno(idl
);
138 if (!ovsdb_idl_is_alive(idl
)) {
139 int retval
= ovsdb_idl_get_last_error(idl
);
140 ctl_fatal("%s: database connection failed (%s)",
141 db
, ovs_retval_to_string(retval
));
144 if (seqno
!= ovsdb_idl_get_seqno(idl
)) {
145 seqno
= ovsdb_idl_get_seqno(idl
);
146 do_vtep_ctl(args
, commands
, n_commands
, idl
);
149 if (seqno
== ovsdb_idl_get_seqno(idl
)) {
157 parse_options(int argc
, char *argv
[], struct shash
*local_options
)
160 OPT_DB
= UCHAR_MAX
+ 1,
169 static const struct option global_long_options
[] = {
170 {"db", required_argument
, NULL
, OPT_DB
},
171 {"no-syslog", no_argument
, NULL
, OPT_NO_SYSLOG
},
172 {"dry-run", no_argument
, NULL
, OPT_DRY_RUN
},
173 {"oneline", no_argument
, NULL
, OPT_ONELINE
},
174 {"timeout", required_argument
, NULL
, 't'},
175 {"help", no_argument
, NULL
, 'h'},
176 {"version", no_argument
, NULL
, 'V'},
179 STREAM_SSL_LONG_OPTIONS
,
180 {"peer-ca-cert", required_argument
, NULL
, OPT_PEER_CA_CERT
},
183 const int n_global_long_options
= ARRAY_SIZE(global_long_options
) - 1;
184 char *tmp
, *short_options
;
186 struct option
*options
;
187 size_t allocated_options
;
191 tmp
= ovs_cmdl_long_options_to_short_options(global_long_options
);
192 short_options
= xasprintf("+%s", tmp
);
195 /* We want to parse both global and command-specific options here, but
196 * getopt_long() isn't too convenient for the job. We copy our global
197 * options into a dynamic array, then append all of the command-specific
199 options
= xmemdup(global_long_options
, sizeof global_long_options
);
200 allocated_options
= ARRAY_SIZE(global_long_options
);
201 n_options
= n_global_long_options
;
202 ctl_add_cmd_options(&options
, &n_options
, &allocated_options
, OPT_LOCAL
);
203 table_style
.format
= TF_LIST
;
209 c
= getopt_long(argc
, argv
, short_options
, options
, &idx
);
224 vlog_set_levels(&VLM_vtep_ctl
, VLF_SYSLOG
, VLL_WARN
);
232 if (shash_find(local_options
, options
[idx
].name
)) {
233 ctl_fatal("'%s' option specified multiple times",
236 shash_add_nocopy(local_options
,
237 xasprintf("--%s", options
[idx
].name
),
238 optarg
? xstrdup(optarg
) : NULL
);
245 ovs_print_version(0, 0);
246 printf("DB Schema %s\n", vteprec_get_db_version());
250 timeout
= strtoul(optarg
, NULL
, 10);
252 ctl_fatal("value %s on -t or --timeout is invalid",
258 TABLE_OPTION_HANDLERS(&table_style
)
260 STREAM_SSL_OPTION_HANDLERS
262 case OPT_PEER_CA_CERT
:
263 stream_ssl_set_peer_ca_cert_file(optarg
);
276 db
= ctl_default_db();
279 for (i
= n_global_long_options
; options
[i
].name
; i
++) {
280 free(CONST_CAST(char *, options
[i
].name
));
285 /* Frees the current transaction and the underlying IDL and then calls
288 * Freeing the transaction and the IDL is not strictly necessary, but it makes
289 * for a clean memory leak report from valgrind in the normal case. That makes
290 * it easier to notice real memory leaks. */
292 vtep_ctl_exit(int status
)
295 ovsdb_idl_txn_abort(the_idl_txn
);
296 ovsdb_idl_txn_destroy(the_idl_txn
);
298 ovsdb_idl_destroy(the_idl
);
306 %s: VTEP configuration utility\n\
307 usage: %s [OPTIONS] COMMAND [ARG...]\n\
310 show print overview of database contents\n\
313 get-manager print the managers\n\
314 del-manager delete the managers\n\
315 set-manager TARGET... set the list of managers to TARGET...\n\
317 Physical Switch commands:\n\
318 add-ps PS create a new physical switch named PS\n\
319 del-ps PS delete PS and all of its ports\n\
320 list-ps print the names of all the physical switches\n\
321 ps-exists PS exit 2 if PS does not exist\n\
324 list-ports PS print the names of all the ports on PS\n\
325 add-port PS PORT add network device PORT to PS\n\
326 del-port PS PORT delete PORT from PS\n\
328 Logical Switch commands:\n\
329 add-ls LS create a new logical switch named LS\n\
330 del-ls LS delete LS and all of its ports\n\
331 list-ls print the names of all the logical switches\n\
332 ls-exists LS exit 2 if LS does not exist\n\
333 bind-ls PS PORT VLAN LS bind LS to VLAN on PORT\n\
334 unbind-ls PS PORT VLAN unbind logical switch on VLAN from PORT\n\
335 list-bindings PS PORT list bindings for PORT on PS\n\
337 MAC binding commands:\n\
338 add-ucast-local LS MAC [ENCAP] IP add ucast local entry in LS\n\
339 del-ucast-local LS MAC del ucast local entry from LS\n\
340 add-mcast-local LS MAC [ENCAP] IP add mcast local entry in LS\n\
341 del-mcast-local LS MAC [ENCAP] IP del mcast local entry from LS\n\
342 clear-local-macs LS clear local mac entries\n\
343 list-local-macs LS list local mac entries\n\
344 add-ucast-remote LS MAC [ENCAP] IP add ucast remote entry in LS\n\
345 del-ucast-remote LS MAC del ucast remote entry from LS\n\
346 add-mcast-remote LS MAC [ENCAP] IP add mcast remote entry in LS\n\
347 del-mcast-remote LS MAC [ENCAP] IP del mcast remote entry from LS\n\
348 clear-remote-macs LS clear remote mac entries\n\
349 list-remote-macs LS list remote mac entries\n\
354 --db=DATABASE connect to DATABASE\n\
356 -t, --timeout=SECS wait at most SECS seconds\n\
357 --dry-run do not commit changes to database\n\
358 --oneline print exactly one line of output per command\n",
359 program_name
, program_name
, ctl_get_db_cmd_usage(), ctl_default_db());
362 --no-syslog equivalent to --verbose=vtep_ctl:syslog:warn\n");
363 stream_usage("database", true, true, false);
366 -h, --help display this help message\n\
367 -V, --version display version information\n");
372 static struct cmd_show_table cmd_show_tables
[] = {
373 {&vteprec_table_global
,
375 {&vteprec_global_col_managers
,
376 &vteprec_global_col_switches
,
381 {&vteprec_table_manager
,
382 &vteprec_manager_col_target
,
383 {&vteprec_manager_col_is_connected
,
389 {&vteprec_table_physical_switch
,
390 &vteprec_physical_switch_col_name
,
391 {&vteprec_physical_switch_col_management_ips
,
392 &vteprec_physical_switch_col_tunnel_ips
,
393 &vteprec_physical_switch_col_ports
},
397 {&vteprec_table_physical_port
,
398 &vteprec_physical_port_col_name
,
399 {&vteprec_physical_port_col_vlan_bindings
,
405 {&vteprec_table_logical_switch
,
406 &vteprec_logical_switch_col_name
,
413 {NULL
, NULL
, {NULL
, NULL
, NULL
}, {NULL
, NULL
, NULL
}}
416 /* vtep-ctl specific context. Inherits the 'struct ctl_context' as base. */
417 struct vtep_ctl_context
{
418 struct ctl_context base
;
420 /* Modifiable state. */
421 const struct vteprec_global
*vtep_global
;
424 /* A cache of the contents of the database.
426 * A command that needs to use any of this information must first
427 * call vtep_ctl_context_populate_cache(). A command that changes
428 * anything that could invalidate the cache must either call
429 * vtep_ctl_context_invalidate_cache() or manually update the cache
430 * to maintain its correctness. */
432 struct shash pswitches
; /* Maps from physical switch name to
433 * struct vtep_ctl_pswitch. */
434 struct shash ports
; /* Maps from port name to struct vtep_ctl_port. */
436 struct shash lswitches
; /* Maps from logical switch name to
437 * struct vtep_ctl_lswitch. */
438 struct shash plocs
; /* Maps from "<encap>+<dst_ip>" to
439 * struct vteprec_physical_locator. */
442 /* Casts 'base' into 'struct vtep_ctl_context'. */
443 static struct vtep_ctl_context
*
444 vtep_ctl_context_cast(struct ctl_context
*base
)
446 return CONTAINER_OF(base
, struct vtep_ctl_context
, base
);
449 struct vtep_ctl_pswitch
{
450 const struct vteprec_physical_switch
*ps_cfg
;
452 struct ovs_list ports
; /* Contains "struct vteprec_physical_port"s. */
455 struct vtep_ctl_port
{
456 struct ovs_list ports_node
; /* In struct vtep_ctl_pswitch's 'ports' list. */
457 const struct vteprec_physical_port
*port_cfg
;
458 struct vtep_ctl_pswitch
*ps
;
459 struct shash bindings
; /* Maps from vlan to vtep_ctl_lswitch. */
462 struct vtep_ctl_lswitch
{
463 const struct vteprec_logical_switch
*ls_cfg
;
465 struct shash ucast_local
; /* Maps from mac to vteprec_ucast_macs_local. */
466 struct shash ucast_remote
; /* Maps from mac to vteprec_ucast_macs_remote.*/
467 struct shash mcast_local
; /* Maps from mac to vtep_ctl_mcast_mac. */
468 struct shash mcast_remote
; /* Maps from mac to vtep_ctl_mcast_mac. */
471 struct vtep_ctl_mcast_mac
{
472 const struct vteprec_mcast_macs_local
*local_cfg
;
473 const struct vteprec_mcast_macs_remote
*remote_cfg
;
475 const struct vteprec_physical_locator_set
*ploc_set_cfg
;
476 struct ovs_list locators
; /* Contains 'vtep_ctl_ploc's. */
479 struct vtep_ctl_ploc
{
480 struct ovs_list locators_node
; /* In struct vtep_ctl_ploc_set's 'locators'
482 const struct vteprec_physical_locator
*ploc_cfg
;
486 verify_ports(struct vtep_ctl_context
*vtepctl_ctx
)
488 if (!vtepctl_ctx
->verified_ports
) {
489 const struct vteprec_physical_switch
*ps
;
491 vteprec_global_verify_switches(vtepctl_ctx
->vtep_global
);
492 VTEPREC_PHYSICAL_SWITCH_FOR_EACH (ps
, vtepctl_ctx
->base
.idl
) {
493 vteprec_physical_switch_verify_ports(ps
);
496 vtepctl_ctx
->verified_ports
= true;
500 static struct vtep_ctl_port
*
501 add_port_to_cache(struct vtep_ctl_context
*vtepctl_ctx
,
502 struct vtep_ctl_pswitch
*ps
,
503 struct vteprec_physical_port
*port_cfg
)
505 char *cache_name
= xasprintf("%s+%s", ps
->name
, port_cfg
->name
);
506 struct vtep_ctl_port
*port
;
508 port
= xmalloc(sizeof *port
);
509 list_push_back(&ps
->ports
, &port
->ports_node
);
510 port
->port_cfg
= port_cfg
;
512 shash_add(&vtepctl_ctx
->ports
, cache_name
, port
);
514 shash_init(&port
->bindings
);
520 del_cached_port(struct vtep_ctl_context
*vtepctl_ctx
,
521 struct vtep_ctl_port
*port
)
523 char *cache_name
= xasprintf("%s+%s", port
->ps
->name
, port
->port_cfg
->name
);
525 list_remove(&port
->ports_node
);
526 shash_find_and_delete(&vtepctl_ctx
->ports
, cache_name
);
527 vteprec_physical_port_delete(port
->port_cfg
);
533 add_pswitch_to_cache(struct vtep_ctl_context
*vtepctl_ctx
,
534 struct vteprec_physical_switch
*ps_cfg
)
536 struct vtep_ctl_pswitch
*ps
= xmalloc(sizeof *ps
);
538 ps
->name
= xstrdup(ps_cfg
->name
);
539 list_init(&ps
->ports
);
540 shash_add(&vtepctl_ctx
->pswitches
, ps
->name
, ps
);
544 vtep_delete_pswitch(const struct vteprec_global
*vtep_global
,
545 const struct vteprec_physical_switch
*ps
)
547 struct vteprec_physical_switch
**pswitches
;
550 pswitches
= xmalloc(sizeof *vtep_global
->switches
551 * vtep_global
->n_switches
);
552 for (i
= n
= 0; i
< vtep_global
->n_switches
; i
++) {
553 if (vtep_global
->switches
[i
] != ps
) {
554 pswitches
[n
++] = vtep_global
->switches
[i
];
557 vteprec_global_set_switches(vtep_global
, pswitches
, n
);
562 del_cached_pswitch(struct vtep_ctl_context
*ctx
, struct vtep_ctl_pswitch
*ps
)
564 ovs_assert(list_is_empty(&ps
->ports
));
566 vteprec_physical_switch_delete(ps
->ps_cfg
);
567 vtep_delete_pswitch(ctx
->vtep_global
, ps
->ps_cfg
);
569 shash_find_and_delete(&ctx
->pswitches
, ps
->name
);
574 static struct vtep_ctl_lswitch
*
575 add_lswitch_to_cache(struct vtep_ctl_context
*vtepctl_ctx
,
576 const struct vteprec_logical_switch
*ls_cfg
)
578 struct vtep_ctl_lswitch
*ls
= xmalloc(sizeof *ls
);
580 ls
->name
= xstrdup(ls_cfg
->name
);
581 shash_add(&vtepctl_ctx
->lswitches
, ls
->name
, ls
);
582 shash_init(&ls
->ucast_local
);
583 shash_init(&ls
->ucast_remote
);
584 shash_init(&ls
->mcast_local
);
585 shash_init(&ls
->mcast_remote
);
590 del_cached_lswitch(struct vtep_ctl_context
*ctx
, struct vtep_ctl_lswitch
*ls
)
593 vteprec_logical_switch_delete(ls
->ls_cfg
);
595 shash_find_and_delete(&ctx
->lswitches
, ls
->name
);
601 commit_ls_bindings(struct vtep_ctl_port
*port
)
603 struct vteprec_logical_switch
**binding_values
;
604 int64_t *binding_keys
;
606 struct shash_node
*node
;
609 n_bindings
= shash_count(&port
->bindings
);
610 binding_keys
= xmalloc(n_bindings
* sizeof *binding_keys
);
611 binding_values
= xmalloc(n_bindings
* sizeof *binding_values
);
614 SHASH_FOR_EACH(node
, &port
->bindings
) {
615 struct vtep_ctl_lswitch
*ls_entry
= node
->data
;
617 binding_keys
[i
] = strtoll(node
->name
, NULL
, 0);
618 binding_values
[i
] = (struct vteprec_logical_switch
*)ls_entry
->ls_cfg
;
622 vteprec_physical_port_set_vlan_bindings(port
->port_cfg
,
623 binding_keys
, binding_values
,
625 free(binding_values
);
630 add_ls_binding_to_cache(struct vtep_ctl_port
*port
,
632 struct vtep_ctl_lswitch
*ls
)
634 if (shash_find(&port
->bindings
, vlan
)) {
635 ctl_fatal("multiple bindings for vlan %s", vlan
);
638 shash_add(&port
->bindings
, vlan
, ls
);
642 del_cached_ls_binding(struct vtep_ctl_port
*port
, const char *vlan
)
644 if (!shash_find(&port
->bindings
, vlan
)) {
645 ctl_fatal("no binding for vlan %s", vlan
);
648 shash_find_and_delete(&port
->bindings
, vlan
);
651 static struct vteprec_physical_locator
*
652 find_ploc(struct vtep_ctl_context
*vtepctl_ctx
, const char *encap
,
655 struct vteprec_physical_locator
*ploc
;
656 char *name
= xasprintf("%s+%s", encap
, dst_ip
);
658 ovs_assert(vtepctl_ctx
->cache_valid
);
660 ploc
= shash_find_data(&vtepctl_ctx
->plocs
, name
);
667 add_ploc_to_cache(struct vtep_ctl_context
*vtepctl_ctx
,
668 struct vteprec_physical_locator
*ploc
)
670 char *name
= xasprintf("%s+%s", ploc
->encapsulation_type
, ploc
->dst_ip
);
671 struct vteprec_physical_locator
*orig_ploc
;
673 orig_ploc
= find_ploc(vtepctl_ctx
, ploc
->encapsulation_type
, ploc
->dst_ip
);
675 shash_add(&vtepctl_ctx
->plocs
, name
, ploc
);
682 add_ploc_to_mcast_mac(struct vtep_ctl_mcast_mac
*mcast_mac
,
683 struct vteprec_physical_locator
*ploc_cfg
)
685 struct vtep_ctl_ploc
*ploc
;
687 ploc
= xmalloc(sizeof *ploc
);
688 ploc
->ploc_cfg
= ploc_cfg
;
689 list_push_back(&mcast_mac
->locators
, &ploc
->locators_node
);
693 del_ploc_from_mcast_mac(struct vtep_ctl_mcast_mac
*mcast_mac
,
694 struct vteprec_physical_locator
*ploc_cfg
)
696 struct vtep_ctl_ploc
*ploc
;
698 LIST_FOR_EACH (ploc
, locators_node
, &mcast_mac
->locators
) {
699 if (ploc
->ploc_cfg
== ploc_cfg
) {
700 list_remove(&ploc
->locators_node
);
707 static struct vtep_ctl_mcast_mac
*
708 add_mcast_mac_to_cache(struct vtep_ctl_context
*vtepctl_ctx
,
709 struct vtep_ctl_lswitch
*ls
, const char *mac
,
710 struct vteprec_physical_locator_set
*ploc_set_cfg
,
713 struct vtep_ctl_mcast_mac
*mcast_mac
;
714 struct shash
*mcast_shash
;
717 mcast_mac
= xmalloc(sizeof *mcast_mac
);
718 mcast_shash
= local
? &ls
->mcast_local
: &ls
->mcast_remote
;
720 mcast_mac
->ploc_set_cfg
= ploc_set_cfg
;
721 list_init(&mcast_mac
->locators
);
722 shash_add(mcast_shash
, mac
, mcast_mac
);
724 for (i
= 0; i
< ploc_set_cfg
->n_locators
; i
++) {
725 struct vteprec_physical_locator
*ploc_cfg
;
727 ploc_cfg
= ploc_set_cfg
->locators
[i
];
728 add_ploc_to_mcast_mac(mcast_mac
, ploc_cfg
);
729 add_ploc_to_cache(vtepctl_ctx
, ploc_cfg
);
736 vtep_ctl_context_invalidate_cache(struct ctl_context
*ctx
)
738 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
739 struct shash_node
*node
;
741 if (!vtepctl_ctx
->cache_valid
) {
744 vtepctl_ctx
->cache_valid
= false;
746 SHASH_FOR_EACH (node
, &vtepctl_ctx
->pswitches
) {
747 struct vtep_ctl_pswitch
*ps
= node
->data
;
751 shash_destroy(&vtepctl_ctx
->pswitches
);
753 SHASH_FOR_EACH (node
, &vtepctl_ctx
->ports
) {
754 struct vtep_ctl_port
*port
= node
->data
;
755 shash_destroy(&port
->bindings
);
757 shash_destroy_free_data(&vtepctl_ctx
->ports
);
759 SHASH_FOR_EACH (node
, &vtepctl_ctx
->lswitches
) {
760 struct vtep_ctl_lswitch
*ls
= node
->data
;
761 struct shash_node
*node2
, *next_node2
;
763 shash_destroy(&ls
->ucast_local
);
764 shash_destroy(&ls
->ucast_remote
);
766 SHASH_FOR_EACH_SAFE (node2
, next_node2
, &ls
->mcast_local
) {
767 struct vtep_ctl_mcast_mac
*mcast_mac
= node2
->data
;
768 struct vtep_ctl_ploc
*ploc
, *next_ploc
;
770 LIST_FOR_EACH_SAFE (ploc
, next_ploc
, locators_node
,
771 &mcast_mac
->locators
) {
776 shash_destroy(&ls
->mcast_local
);
778 SHASH_FOR_EACH_SAFE (node2
, next_node2
, &ls
->mcast_remote
) {
779 struct vtep_ctl_mcast_mac
*mcast_mac
= node2
->data
;
780 struct vtep_ctl_ploc
*ploc
, *next_ploc
;
782 LIST_FOR_EACH_SAFE (ploc
, next_ploc
, locators_node
,
783 &mcast_mac
->locators
) {
788 shash_destroy(&ls
->mcast_remote
);
793 shash_destroy(&vtepctl_ctx
->lswitches
);
794 shash_destroy(&vtepctl_ctx
->plocs
);
798 pre_get_info(struct ctl_context
*ctx
)
800 ovsdb_idl_add_column(ctx
->idl
, &vteprec_global_col_switches
);
802 ovsdb_idl_add_column(ctx
->idl
, &vteprec_physical_switch_col_name
);
803 ovsdb_idl_add_column(ctx
->idl
, &vteprec_physical_switch_col_ports
);
804 ovsdb_idl_add_column(ctx
->idl
, &vteprec_physical_switch_col_tunnels
);
806 ovsdb_idl_add_column(ctx
->idl
, &vteprec_physical_port_col_name
);
807 ovsdb_idl_add_column(ctx
->idl
, &vteprec_physical_port_col_vlan_bindings
);
809 ovsdb_idl_add_column(ctx
->idl
, &vteprec_logical_switch_col_name
);
811 ovsdb_idl_add_column(ctx
->idl
, &vteprec_ucast_macs_local_col_MAC
);
812 ovsdb_idl_add_column(ctx
->idl
, &vteprec_ucast_macs_local_col_locator
);
813 ovsdb_idl_add_column(ctx
->idl
,
814 &vteprec_ucast_macs_local_col_logical_switch
);
816 ovsdb_idl_add_column(ctx
->idl
, &vteprec_ucast_macs_remote_col_MAC
);
817 ovsdb_idl_add_column(ctx
->idl
, &vteprec_ucast_macs_remote_col_locator
);
818 ovsdb_idl_add_column(ctx
->idl
,
819 &vteprec_ucast_macs_remote_col_logical_switch
);
821 ovsdb_idl_add_column(ctx
->idl
, &vteprec_mcast_macs_local_col_MAC
);
822 ovsdb_idl_add_column(ctx
->idl
,
823 &vteprec_mcast_macs_local_col_locator_set
);
824 ovsdb_idl_add_column(ctx
->idl
,
825 &vteprec_mcast_macs_local_col_logical_switch
);
827 ovsdb_idl_add_column(ctx
->idl
, &vteprec_mcast_macs_remote_col_MAC
);
828 ovsdb_idl_add_column(ctx
->idl
,
829 &vteprec_mcast_macs_remote_col_locator_set
);
830 ovsdb_idl_add_column(ctx
->idl
,
831 &vteprec_mcast_macs_remote_col_logical_switch
);
833 ovsdb_idl_add_column(ctx
->idl
,
834 &vteprec_physical_locator_set_col_locators
);
836 ovsdb_idl_add_column(ctx
->idl
,
837 &vteprec_physical_locator_col_dst_ip
);
838 ovsdb_idl_add_column(ctx
->idl
,
839 &vteprec_physical_locator_col_encapsulation_type
);
841 ovsdb_idl_add_column(ctx
->idl
, &vteprec_tunnel_col_local
);
842 ovsdb_idl_add_column(ctx
->idl
, &vteprec_tunnel_col_remote
);
846 vtep_ctl_context_populate_cache(struct ctl_context
*ctx
)
848 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
849 const struct vteprec_global
*vtep_global
= vtepctl_ctx
->vtep_global
;
850 const struct vteprec_logical_switch
*ls_cfg
;
851 const struct vteprec_ucast_macs_local
*ucast_local_cfg
;
852 const struct vteprec_ucast_macs_remote
*ucast_remote_cfg
;
853 const struct vteprec_mcast_macs_local
*mcast_local_cfg
;
854 const struct vteprec_mcast_macs_remote
*mcast_remote_cfg
;
855 const struct vteprec_tunnel
*tunnel_cfg
;
856 struct sset pswitches
, ports
, lswitches
;
859 if (vtepctl_ctx
->cache_valid
) {
860 /* Cache is already populated. */
863 vtepctl_ctx
->cache_valid
= true;
864 shash_init(&vtepctl_ctx
->pswitches
);
865 shash_init(&vtepctl_ctx
->ports
);
866 shash_init(&vtepctl_ctx
->lswitches
);
867 shash_init(&vtepctl_ctx
->plocs
);
869 sset_init(&pswitches
);
871 for (i
= 0; i
< vtep_global
->n_switches
; i
++) {
872 struct vteprec_physical_switch
*ps_cfg
= vtep_global
->switches
[i
];
875 if (!sset_add(&pswitches
, ps_cfg
->name
)) {
876 VLOG_WARN("%s: database contains duplicate physical switch name",
880 add_pswitch_to_cache(vtepctl_ctx
, ps_cfg
);
882 for (j
= 0; j
< ps_cfg
->n_ports
; j
++) {
883 struct vteprec_physical_port
*port_cfg
= ps_cfg
->ports
[j
];
885 if (!sset_add(&ports
, port_cfg
->name
)) {
886 /* Duplicate port name. (We will warn about that later.) */
891 sset_destroy(&pswitches
);
892 sset_destroy(&ports
);
894 sset_init(&lswitches
);
895 VTEPREC_LOGICAL_SWITCH_FOR_EACH (ls_cfg
, ctx
->idl
) {
896 if (!sset_add(&lswitches
, ls_cfg
->name
)) {
897 VLOG_WARN("%s: database contains duplicate logical switch name",
901 add_lswitch_to_cache(vtepctl_ctx
, ls_cfg
);
903 sset_destroy(&lswitches
);
905 VTEPREC_UCAST_MACS_LOCAL_FOR_EACH (ucast_local_cfg
, ctx
->idl
) {
906 struct vtep_ctl_lswitch
*ls
;
908 if (!ucast_local_cfg
->logical_switch
) {
911 ls
= find_lswitch(vtepctl_ctx
, ucast_local_cfg
->logical_switch
->name
,
917 if (ucast_local_cfg
->locator
) {
918 add_ploc_to_cache(vtepctl_ctx
, ucast_local_cfg
->locator
);
921 shash_add(&ls
->ucast_local
, ucast_local_cfg
->MAC
, ucast_local_cfg
);
924 VTEPREC_UCAST_MACS_REMOTE_FOR_EACH (ucast_remote_cfg
, ctx
->idl
) {
925 struct vtep_ctl_lswitch
*ls
;
927 if (!ucast_remote_cfg
->logical_switch
) {
930 ls
= find_lswitch(vtepctl_ctx
, ucast_remote_cfg
->logical_switch
->name
,
936 if (ucast_remote_cfg
->locator
) {
937 add_ploc_to_cache(vtepctl_ctx
, ucast_remote_cfg
->locator
);
940 shash_add(&ls
->ucast_remote
, ucast_remote_cfg
->MAC
, ucast_remote_cfg
);
943 VTEPREC_MCAST_MACS_LOCAL_FOR_EACH (mcast_local_cfg
, ctx
->idl
) {
944 struct vtep_ctl_mcast_mac
*mcast_mac
;
945 struct vtep_ctl_lswitch
*ls
;
947 if (!mcast_local_cfg
->logical_switch
) {
950 ls
= find_lswitch(vtepctl_ctx
, mcast_local_cfg
->logical_switch
->name
,
956 mcast_mac
= add_mcast_mac_to_cache(vtepctl_ctx
, ls
, mcast_local_cfg
->MAC
,
957 mcast_local_cfg
->locator_set
,
959 mcast_mac
->local_cfg
= mcast_local_cfg
;
962 VTEPREC_MCAST_MACS_REMOTE_FOR_EACH (mcast_remote_cfg
, ctx
->idl
) {
963 struct vtep_ctl_mcast_mac
*mcast_mac
;
964 struct vtep_ctl_lswitch
*ls
;
966 if (!mcast_remote_cfg
->logical_switch
) {
969 ls
= find_lswitch(vtepctl_ctx
, mcast_remote_cfg
->logical_switch
->name
,
975 mcast_mac
= add_mcast_mac_to_cache(vtepctl_ctx
, ls
, mcast_remote_cfg
->MAC
,
976 mcast_remote_cfg
->locator_set
,
978 mcast_mac
->remote_cfg
= mcast_remote_cfg
;
981 VTEPREC_TUNNEL_FOR_EACH (tunnel_cfg
, ctx
->idl
) {
982 if (tunnel_cfg
->local
) {
983 add_ploc_to_cache(vtepctl_ctx
, tunnel_cfg
->local
);
985 if (tunnel_cfg
->remote
) {
986 add_ploc_to_cache(vtepctl_ctx
, tunnel_cfg
->remote
);
990 sset_init(&pswitches
);
991 for (i
= 0; i
< vtep_global
->n_switches
; i
++) {
992 struct vteprec_physical_switch
*ps_cfg
= vtep_global
->switches
[i
];
993 struct vtep_ctl_pswitch
*ps
;
996 if (!sset_add(&pswitches
, ps_cfg
->name
)) {
999 ps
= shash_find_data(&vtepctl_ctx
->pswitches
, ps_cfg
->name
);
1000 for (j
= 0; j
< ps_cfg
->n_ports
; j
++) {
1001 struct vteprec_physical_port
*port_cfg
= ps_cfg
->ports
[j
];
1002 struct vtep_ctl_port
*port
;
1005 port
= shash_find_data(&vtepctl_ctx
->ports
, port_cfg
->name
);
1007 if (port_cfg
== port
->port_cfg
) {
1008 VLOG_WARN("%s: port is in multiple physical switches "
1010 port_cfg
->name
, ps
->name
, port
->ps
->name
);
1012 /* Log as an error because this violates the database's
1013 * uniqueness constraints, so the database server shouldn't
1014 * have allowed it. */
1015 VLOG_ERR("%s: database contains duplicate port name",
1021 port
= add_port_to_cache(vtepctl_ctx
, ps
, port_cfg
);
1023 for (k
= 0; k
< port_cfg
->n_vlan_bindings
; k
++) {
1024 struct vteprec_logical_switch
*ls_cfg
;
1025 struct vtep_ctl_lswitch
*ls
;
1028 vlan
= xasprintf("%"PRId64
, port_cfg
->key_vlan_bindings
[k
]);
1029 if (shash_find(&port
->bindings
, vlan
)) {
1030 ctl_fatal("multiple bindings for vlan %s", vlan
);
1033 ls_cfg
= port_cfg
->value_vlan_bindings
[k
];
1034 ls
= find_lswitch(vtepctl_ctx
, ls_cfg
->name
, true);
1036 shash_add_nocopy(&port
->bindings
, vlan
, ls
);
1040 sset_destroy(&pswitches
);
1043 static struct vtep_ctl_pswitch
*
1044 find_pswitch(struct vtep_ctl_context
*vtepctl_ctx
, const char *name
, bool must_exist
)
1046 struct vtep_ctl_pswitch
*ps
;
1048 ovs_assert(vtepctl_ctx
->cache_valid
);
1050 ps
= shash_find_data(&vtepctl_ctx
->pswitches
, name
);
1051 if (must_exist
&& !ps
) {
1052 ctl_fatal("no physical switch named %s", name
);
1054 vteprec_global_verify_switches(vtepctl_ctx
->vtep_global
);
1058 static struct vtep_ctl_port
*
1059 find_port(struct vtep_ctl_context
*vtepctl_ctx
, const char *ps_name
,
1060 const char *port_name
, bool must_exist
)
1062 char *cache_name
= xasprintf("%s+%s", ps_name
, port_name
);
1063 struct vtep_ctl_port
*port
;
1065 ovs_assert(vtepctl_ctx
->cache_valid
);
1067 port
= shash_find_data(&vtepctl_ctx
->ports
, cache_name
);
1068 if (port
&& !strcmp(port_name
, port
->ps
->name
)) {
1072 if (must_exist
&& !port
) {
1073 ctl_fatal("no port named %s", port_name
);
1075 verify_ports(vtepctl_ctx
);
1080 pswitch_insert_port(const struct vteprec_physical_switch
*ps
,
1081 struct vteprec_physical_port
*port
)
1083 struct vteprec_physical_port
**ports
;
1086 ports
= xmalloc(sizeof *ps
->ports
* (ps
->n_ports
+ 1));
1087 for (i
= 0; i
< ps
->n_ports
; i
++) {
1088 ports
[i
] = ps
->ports
[i
];
1090 ports
[ps
->n_ports
] = port
;
1091 vteprec_physical_switch_set_ports(ps
, ports
, ps
->n_ports
+ 1);
1096 pswitch_delete_port(const struct vteprec_physical_switch
*ps
,
1097 const struct vteprec_physical_port
*port
)
1099 struct vteprec_physical_port
**ports
;
1102 ports
= xmalloc(sizeof *ps
->ports
* ps
->n_ports
);
1103 for (i
= n
= 0; i
< ps
->n_ports
; i
++) {
1104 if (ps
->ports
[i
] != port
) {
1105 ports
[n
++] = ps
->ports
[i
];
1108 vteprec_physical_switch_set_ports(ps
, ports
, n
);
1113 vtep_insert_pswitch(const struct vteprec_global
*vtep_global
,
1114 struct vteprec_physical_switch
*ps
)
1116 struct vteprec_physical_switch
**pswitches
;
1119 pswitches
= xmalloc(sizeof *vtep_global
->switches
1120 * (vtep_global
->n_switches
+ 1));
1121 for (i
= 0; i
< vtep_global
->n_switches
; i
++) {
1122 pswitches
[i
] = vtep_global
->switches
[i
];
1124 pswitches
[vtep_global
->n_switches
] = ps
;
1125 vteprec_global_set_switches(vtep_global
, pswitches
,
1126 vtep_global
->n_switches
+ 1);
1131 cmd_add_ps(struct ctl_context
*ctx
)
1133 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1134 const char *ps_name
= ctx
->argv
[1];
1135 bool may_exist
= shash_find(&ctx
->options
, "--may-exist") != NULL
;
1136 struct vteprec_physical_switch
*ps
;
1138 vtep_ctl_context_populate_cache(ctx
);
1139 if (find_pswitch(vtepctl_ctx
, ps_name
, false)) {
1141 ctl_fatal("cannot create physical switch %s because it "
1142 "already exists", ps_name
);
1147 ps
= vteprec_physical_switch_insert(ctx
->txn
);
1148 vteprec_physical_switch_set_name(ps
, ps_name
);
1150 vtep_insert_pswitch(vtepctl_ctx
->vtep_global
, ps
);
1152 vtep_ctl_context_invalidate_cache(ctx
);
1156 del_port(struct vtep_ctl_context
*vtepctl_ctx
, struct vtep_ctl_port
*port
)
1158 pswitch_delete_port(port
->ps
->ps_cfg
, port
->port_cfg
);
1159 del_cached_port(vtepctl_ctx
, port
);
1163 del_pswitch(struct vtep_ctl_context
*vtepctl_ctx
, struct vtep_ctl_pswitch
*ps
)
1165 struct vtep_ctl_port
*port
, *next_port
;
1167 LIST_FOR_EACH_SAFE (port
, next_port
, ports_node
, &ps
->ports
) {
1168 del_port(vtepctl_ctx
, port
);
1171 del_cached_pswitch(vtepctl_ctx
, ps
);
1175 cmd_del_ps(struct ctl_context
*ctx
)
1177 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1178 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1179 struct vtep_ctl_pswitch
*ps
;
1181 vtep_ctl_context_populate_cache(ctx
);
1182 ps
= find_pswitch(vtepctl_ctx
, ctx
->argv
[1], must_exist
);
1184 del_pswitch(vtepctl_ctx
, ps
);
1189 output_sorted(struct svec
*svec
, struct ds
*output
)
1195 SVEC_FOR_EACH (i
, name
, svec
) {
1196 ds_put_format(output
, "%s\n", name
);
1201 cmd_list_ps(struct ctl_context
*ctx
)
1203 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1204 struct shash_node
*node
;
1205 struct svec pswitches
;
1207 vtep_ctl_context_populate_cache(ctx
);
1209 svec_init(&pswitches
);
1210 SHASH_FOR_EACH (node
, &vtepctl_ctx
->pswitches
) {
1211 struct vtep_ctl_pswitch
*ps
= node
->data
;
1213 svec_add(&pswitches
, ps
->name
);
1215 output_sorted(&pswitches
, &ctx
->output
);
1216 svec_destroy(&pswitches
);
1220 cmd_ps_exists(struct ctl_context
*ctx
)
1222 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1224 vtep_ctl_context_populate_cache(ctx
);
1225 if (!find_pswitch(vtepctl_ctx
, ctx
->argv
[1], false)) {
1231 cmd_list_ports(struct ctl_context
*ctx
)
1233 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1234 struct vtep_ctl_pswitch
*ps
;
1235 struct vtep_ctl_port
*port
;
1238 vtep_ctl_context_populate_cache(ctx
);
1239 ps
= find_pswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1240 vteprec_physical_switch_verify_ports(ps
->ps_cfg
);
1243 LIST_FOR_EACH (port
, ports_node
, &ps
->ports
) {
1244 if (strcmp(port
->port_cfg
->name
, ps
->name
)) {
1245 svec_add(&ports
, port
->port_cfg
->name
);
1248 output_sorted(&ports
, &ctx
->output
);
1249 svec_destroy(&ports
);
1253 add_port(struct ctl_context
*ctx
, const char *ps_name
,
1254 const char *port_name
, bool may_exist
)
1256 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1257 struct vtep_ctl_port
*vtep_ctl_port
;
1258 struct vtep_ctl_pswitch
*ps
;
1259 struct vteprec_physical_port
*port
;
1261 vtep_ctl_context_populate_cache(ctx
);
1263 vtep_ctl_port
= find_port(vtepctl_ctx
, ps_name
, port_name
, false);
1264 if (vtep_ctl_port
) {
1266 ctl_fatal("cannot create a port named %s on %s because a "
1267 "port with that name already exists",
1268 port_name
, ps_name
);
1273 ps
= find_pswitch(vtepctl_ctx
, ps_name
, true);
1275 port
= vteprec_physical_port_insert(ctx
->txn
);
1276 vteprec_physical_port_set_name(port
, port_name
);
1278 pswitch_insert_port(ps
->ps_cfg
, port
);
1280 add_port_to_cache(vtepctl_ctx
, ps
, port
);
1284 cmd_add_port(struct ctl_context
*ctx
)
1286 bool may_exist
= shash_find(&ctx
->options
, "--may-exist") != NULL
;
1288 add_port(ctx
, ctx
->argv
[1], ctx
->argv
[2], may_exist
);
1292 cmd_del_port(struct ctl_context
*ctx
)
1294 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1295 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1296 struct vtep_ctl_port
*port
;
1298 vtep_ctl_context_populate_cache(ctx
);
1300 port
= find_port(vtepctl_ctx
, ctx
->argv
[1], ctx
->argv
[2], must_exist
);
1302 if (ctx
->argc
== 3) {
1303 struct vtep_ctl_pswitch
*ps
;
1305 ps
= find_pswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1306 if (port
->ps
!= ps
) {
1307 ctl_fatal("physical switch %s does not have a port %s",
1308 ctx
->argv
[1], ctx
->argv
[2]);
1312 del_port(vtepctl_ctx
, port
);
1316 static struct vtep_ctl_lswitch
*
1317 find_lswitch(struct vtep_ctl_context
*vtepctl_ctx
,
1318 const char *name
, bool must_exist
)
1320 struct vtep_ctl_lswitch
*ls
;
1322 ovs_assert(vtepctl_ctx
->cache_valid
);
1324 ls
= shash_find_data(&vtepctl_ctx
->lswitches
, name
);
1325 if (must_exist
&& !ls
) {
1326 ctl_fatal("no logical switch named %s", name
);
1332 cmd_add_ls(struct ctl_context
*ctx
)
1334 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1335 const char *ls_name
= ctx
->argv
[1];
1336 bool may_exist
= shash_find(&ctx
->options
, "--may-exist") != NULL
;
1337 struct vteprec_logical_switch
*ls
;
1339 vtep_ctl_context_populate_cache(ctx
);
1340 if (find_lswitch(vtepctl_ctx
, ls_name
, false)) {
1342 ctl_fatal("cannot create logical switch %s because it "
1343 "already exists", ls_name
);
1348 ls
= vteprec_logical_switch_insert(ctx
->txn
);
1349 vteprec_logical_switch_set_name(ls
, ls_name
);
1351 vtep_ctl_context_invalidate_cache(ctx
);
1355 del_lswitch(struct vtep_ctl_context
*vtepctl_ctx
, struct vtep_ctl_lswitch
*ls
)
1357 del_cached_lswitch(vtepctl_ctx
, ls
);
1361 cmd_del_ls(struct ctl_context
*ctx
)
1363 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1364 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1365 struct vtep_ctl_lswitch
*ls
;
1367 vtep_ctl_context_populate_cache(ctx
);
1368 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], must_exist
);
1370 del_lswitch(vtepctl_ctx
, ls
);
1375 cmd_list_ls(struct ctl_context
*ctx
)
1377 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1378 struct shash_node
*node
;
1379 struct svec lswitches
;
1381 vtep_ctl_context_populate_cache(ctx
);
1383 svec_init(&lswitches
);
1384 SHASH_FOR_EACH (node
, &vtepctl_ctx
->lswitches
) {
1385 struct vtep_ctl_lswitch
*ls
= node
->data
;
1387 svec_add(&lswitches
, ls
->name
);
1389 output_sorted(&lswitches
, &ctx
->output
);
1390 svec_destroy(&lswitches
);
1394 cmd_ls_exists(struct ctl_context
*ctx
)
1396 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1398 vtep_ctl_context_populate_cache(ctx
);
1399 if (!find_lswitch(vtepctl_ctx
, ctx
->argv
[1], false)) {
1405 cmd_list_bindings(struct ctl_context
*ctx
)
1407 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1408 const struct shash_node
*node
;
1409 struct vtep_ctl_port
*port
;
1410 struct svec bindings
;
1412 vtep_ctl_context_populate_cache(ctx
);
1413 port
= find_port(vtepctl_ctx
, ctx
->argv
[1], ctx
->argv
[2], true);
1415 svec_init(&bindings
);
1416 SHASH_FOR_EACH (node
, &port
->bindings
) {
1417 struct vtep_ctl_lswitch
*lswitch
= node
->data
;
1420 binding
= xasprintf("%04lld %s", strtoll(node
->name
, NULL
, 0),
1422 svec_add_nocopy(&bindings
, binding
);
1424 output_sorted(&bindings
, &ctx
->output
);
1425 svec_destroy(&bindings
);
1429 cmd_bind_ls(struct ctl_context
*ctx
)
1431 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1432 struct vtep_ctl_lswitch
*ls
;
1433 struct vtep_ctl_port
*port
;
1436 vtep_ctl_context_populate_cache(ctx
);
1438 port
= find_port(vtepctl_ctx
, ctx
->argv
[1], ctx
->argv
[2], true);
1439 vlan
= ctx
->argv
[3];
1440 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[4], true);
1442 add_ls_binding_to_cache(port
, vlan
, ls
);
1443 commit_ls_bindings(port
);
1445 vtep_ctl_context_invalidate_cache(ctx
);
1449 cmd_unbind_ls(struct ctl_context
*ctx
)
1451 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1452 struct vtep_ctl_port
*port
;
1455 vtep_ctl_context_populate_cache(ctx
);
1457 port
= find_port(vtepctl_ctx
, ctx
->argv
[1], ctx
->argv
[2], true);
1458 vlan
= ctx
->argv
[3];
1460 del_cached_ls_binding(port
, vlan
);
1461 commit_ls_bindings(port
);
1463 vtep_ctl_context_invalidate_cache(ctx
);
1467 add_ucast_entry(struct ctl_context
*ctx
, bool local
)
1469 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1470 struct vtep_ctl_lswitch
*ls
;
1474 struct vteprec_physical_locator
*ploc_cfg
;
1476 vtep_ctl_context_populate_cache(ctx
);
1478 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1481 if (ctx
->argc
== 4) {
1482 encap
= "vxlan_over_ipv4";
1483 dst_ip
= ctx
->argv
[3];
1485 encap
= ctx
->argv
[3];
1486 dst_ip
= ctx
->argv
[4];
1489 ploc_cfg
= find_ploc(vtepctl_ctx
, encap
, dst_ip
);
1491 ploc_cfg
= vteprec_physical_locator_insert(ctx
->txn
);
1492 vteprec_physical_locator_set_dst_ip(ploc_cfg
, dst_ip
);
1493 vteprec_physical_locator_set_encapsulation_type(ploc_cfg
, encap
);
1495 add_ploc_to_cache(vtepctl_ctx
, ploc_cfg
);
1499 struct vteprec_ucast_macs_local
*ucast_cfg
;
1501 ucast_cfg
= shash_find_data(&ls
->ucast_local
, mac
);
1503 ucast_cfg
= vteprec_ucast_macs_local_insert(ctx
->txn
);
1504 vteprec_ucast_macs_local_set_MAC(ucast_cfg
, mac
);
1505 vteprec_ucast_macs_local_set_logical_switch(ucast_cfg
, ls
->ls_cfg
);
1506 shash_add(&ls
->ucast_local
, mac
, ucast_cfg
);
1508 vteprec_ucast_macs_local_set_locator(ucast_cfg
, ploc_cfg
);
1510 struct vteprec_ucast_macs_remote
*ucast_cfg
;
1512 ucast_cfg
= shash_find_data(&ls
->ucast_remote
, mac
);
1514 ucast_cfg
= vteprec_ucast_macs_remote_insert(ctx
->txn
);
1515 vteprec_ucast_macs_remote_set_MAC(ucast_cfg
, mac
);
1516 vteprec_ucast_macs_remote_set_logical_switch(ucast_cfg
, ls
->ls_cfg
);
1517 shash_add(&ls
->ucast_remote
, mac
, ucast_cfg
);
1519 vteprec_ucast_macs_remote_set_locator(ucast_cfg
, ploc_cfg
);
1522 vtep_ctl_context_invalidate_cache(ctx
);
1526 cmd_add_ucast_local(struct ctl_context
*ctx
)
1528 add_ucast_entry(ctx
, true);
1532 cmd_add_ucast_remote(struct ctl_context
*ctx
)
1534 add_ucast_entry(ctx
, false);
1538 del_ucast_entry(struct ctl_context
*ctx
, bool local
)
1540 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1541 struct vtep_ctl_lswitch
*ls
;
1542 struct shash
*ucast_shash
;
1543 struct shash_node
*node
;
1545 vtep_ctl_context_populate_cache(ctx
);
1547 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1548 ucast_shash
= local
? &ls
->ucast_local
: &ls
->ucast_remote
;
1550 node
= shash_find(ucast_shash
, ctx
->argv
[2]);
1556 struct vteprec_ucast_macs_local
*ucast_cfg
= node
->data
;
1557 vteprec_ucast_macs_local_delete(ucast_cfg
);
1559 struct vteprec_ucast_macs_remote
*ucast_cfg
= node
->data
;
1560 vteprec_ucast_macs_remote_delete(ucast_cfg
);
1562 shash_delete(ucast_shash
, node
);
1564 vtep_ctl_context_invalidate_cache(ctx
);
1568 cmd_del_ucast_local(struct ctl_context
*ctx
)
1570 del_ucast_entry(ctx
, true);
1574 cmd_del_ucast_remote(struct ctl_context
*ctx
)
1576 del_ucast_entry(ctx
, false);
1580 commit_mcast_entries(struct vtep_ctl_mcast_mac
*mcast_mac
)
1582 struct vtep_ctl_ploc
*ploc
;
1583 struct vteprec_physical_locator
**locators
= NULL
;
1587 n_locators
= list_size(&mcast_mac
->locators
);
1588 ovs_assert(n_locators
);
1590 locators
= xmalloc(n_locators
* sizeof *locators
);
1593 LIST_FOR_EACH (ploc
, locators_node
, &mcast_mac
->locators
) {
1594 locators
[i
] = (struct vteprec_physical_locator
*)ploc
->ploc_cfg
;
1598 vteprec_physical_locator_set_set_locators(mcast_mac
->ploc_set_cfg
,
1606 add_mcast_entry(struct ctl_context
*ctx
,
1607 struct vtep_ctl_lswitch
*ls
, const char *mac
,
1608 const char *encap
, const char *dst_ip
, bool local
)
1610 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1611 struct shash
*mcast_shash
;
1612 struct vtep_ctl_mcast_mac
*mcast_mac
;
1613 struct vteprec_physical_locator
*ploc_cfg
;
1614 struct vteprec_physical_locator_set
*ploc_set_cfg
;
1616 mcast_shash
= local
? &ls
->mcast_local
: &ls
->mcast_remote
;
1618 /* Physical locator sets are immutable, so allocate a new one. */
1619 ploc_set_cfg
= vteprec_physical_locator_set_insert(ctx
->txn
);
1621 mcast_mac
= shash_find_data(mcast_shash
, mac
);
1623 mcast_mac
= add_mcast_mac_to_cache(vtepctl_ctx
, ls
, mac
, ploc_set_cfg
,
1627 mcast_mac
->local_cfg
= vteprec_mcast_macs_local_insert(ctx
->txn
);
1628 vteprec_mcast_macs_local_set_MAC(mcast_mac
->local_cfg
, mac
);
1629 vteprec_mcast_macs_local_set_locator_set(mcast_mac
->local_cfg
,
1631 vteprec_mcast_macs_local_set_logical_switch(mcast_mac
->local_cfg
,
1633 mcast_mac
->remote_cfg
= NULL
;
1635 mcast_mac
->remote_cfg
= vteprec_mcast_macs_remote_insert(ctx
->txn
);
1636 vteprec_mcast_macs_remote_set_MAC(mcast_mac
->remote_cfg
, mac
);
1637 vteprec_mcast_macs_remote_set_locator_set(mcast_mac
->remote_cfg
,
1639 vteprec_mcast_macs_remote_set_logical_switch(mcast_mac
->remote_cfg
,
1641 mcast_mac
->local_cfg
= NULL
;
1644 mcast_mac
->ploc_set_cfg
= ploc_set_cfg
;
1646 vteprec_mcast_macs_local_set_locator_set(mcast_mac
->local_cfg
,
1649 vteprec_mcast_macs_remote_set_locator_set(mcast_mac
->remote_cfg
,
1654 ploc_cfg
= find_ploc(vtepctl_ctx
, encap
, dst_ip
);
1656 ploc_cfg
= vteprec_physical_locator_insert(ctx
->txn
);
1657 vteprec_physical_locator_set_dst_ip(ploc_cfg
, dst_ip
);
1658 vteprec_physical_locator_set_encapsulation_type(ploc_cfg
, encap
);
1660 add_ploc_to_cache(vtepctl_ctx
, ploc_cfg
);
1663 add_ploc_to_mcast_mac(mcast_mac
, ploc_cfg
);
1664 commit_mcast_entries(mcast_mac
);
1668 del_mcast_entry(struct ctl_context
*ctx
,
1669 struct vtep_ctl_lswitch
*ls
, const char *mac
,
1670 const char *encap
, const char *dst_ip
, bool local
)
1672 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1673 struct vtep_ctl_mcast_mac
*mcast_mac
;
1674 struct shash
*mcast_shash
;
1675 struct vteprec_physical_locator
*ploc_cfg
;
1676 struct vteprec_physical_locator_set
*ploc_set_cfg
;
1678 mcast_shash
= local
? &ls
->mcast_local
: &ls
->mcast_remote
;
1680 mcast_mac
= shash_find_data(mcast_shash
, mac
);
1685 ploc_cfg
= find_ploc(vtepctl_ctx
, encap
, dst_ip
);
1687 /* Couldn't find the physical locator, so just ignore. */
1691 /* Physical locator sets are immutable, so allocate a new one. */
1692 ploc_set_cfg
= vteprec_physical_locator_set_insert(ctx
->txn
);
1693 mcast_mac
->ploc_set_cfg
= ploc_set_cfg
;
1695 del_ploc_from_mcast_mac(mcast_mac
, ploc_cfg
);
1696 if (list_is_empty(&mcast_mac
->locators
)) {
1697 struct shash_node
*node
= shash_find(mcast_shash
, mac
);
1699 vteprec_physical_locator_set_delete(ploc_set_cfg
);
1702 vteprec_mcast_macs_local_delete(mcast_mac
->local_cfg
);
1704 vteprec_mcast_macs_remote_delete(mcast_mac
->remote_cfg
);
1708 shash_delete(mcast_shash
, node
);
1711 vteprec_mcast_macs_local_set_locator_set(mcast_mac
->local_cfg
,
1714 vteprec_mcast_macs_remote_set_locator_set(mcast_mac
->remote_cfg
,
1717 commit_mcast_entries(mcast_mac
);
1722 add_del_mcast_entry(struct ctl_context
*ctx
, bool add
, bool local
)
1724 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1725 struct vtep_ctl_lswitch
*ls
;
1730 vtep_ctl_context_populate_cache(ctx
);
1732 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1735 if (ctx
->argc
== 4) {
1736 encap
= "vxlan_over_ipv4";
1737 dst_ip
= ctx
->argv
[3];
1739 encap
= ctx
->argv
[3];
1740 dst_ip
= ctx
->argv
[4];
1744 add_mcast_entry(ctx
, ls
, mac
, encap
, dst_ip
, local
);
1746 del_mcast_entry(ctx
, ls
, mac
, encap
, dst_ip
, local
);
1749 vtep_ctl_context_invalidate_cache(ctx
);
1753 cmd_add_mcast_local(struct ctl_context
*ctx
)
1755 add_del_mcast_entry(ctx
, true, true);
1759 cmd_add_mcast_remote(struct ctl_context
*ctx
)
1761 add_del_mcast_entry(ctx
, true, false);
1765 cmd_del_mcast_local(struct ctl_context
*ctx
)
1767 add_del_mcast_entry(ctx
, false, true);
1771 cmd_del_mcast_remote(struct ctl_context
*ctx
)
1773 add_del_mcast_entry(ctx
, false, false);
1777 clear_macs(struct ctl_context
*ctx
, bool local
)
1779 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1780 struct vtep_ctl_lswitch
*ls
;
1781 const struct shash_node
*node
;
1782 struct shash
*ucast_shash
;
1783 struct shash
*mcast_shash
;
1785 vtep_ctl_context_populate_cache(ctx
);
1786 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1788 ucast_shash
= local
? &ls
->ucast_local
: &ls
->ucast_remote
;
1789 mcast_shash
= local
? &ls
->mcast_local
: &ls
->mcast_remote
;
1791 SHASH_FOR_EACH (node
, ucast_shash
) {
1793 struct vteprec_ucast_macs_local
*ucast_cfg
= node
->data
;
1794 vteprec_ucast_macs_local_delete(ucast_cfg
);
1796 struct vteprec_ucast_macs_remote
*ucast_cfg
= node
->data
;
1797 vteprec_ucast_macs_remote_delete(ucast_cfg
);
1801 SHASH_FOR_EACH (node
, mcast_shash
) {
1802 struct vtep_ctl_mcast_mac
*mcast_mac
= node
->data
;
1804 vteprec_mcast_macs_local_delete(mcast_mac
->local_cfg
);
1806 vteprec_mcast_macs_remote_delete(mcast_mac
->remote_cfg
);
1810 vtep_ctl_context_invalidate_cache(ctx
);
1814 cmd_clear_local_macs(struct ctl_context
*ctx
)
1816 clear_macs(ctx
, true);
1820 cmd_clear_remote_macs(struct ctl_context
*ctx
)
1822 clear_macs(ctx
, false);
1826 list_macs(struct ctl_context
*ctx
, bool local
)
1828 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1829 struct vtep_ctl_lswitch
*ls
;
1830 const struct shash_node
*node
;
1831 struct shash
*ucast_shash
;
1832 struct svec ucast_macs
;
1833 struct shash
*mcast_shash
;
1834 struct svec mcast_macs
;
1836 vtep_ctl_context_populate_cache(ctx
);
1837 ls
= find_lswitch(vtepctl_ctx
, ctx
->argv
[1], true);
1839 ucast_shash
= local
? &ls
->ucast_local
: &ls
->ucast_remote
;
1840 mcast_shash
= local
? &ls
->mcast_local
: &ls
->mcast_remote
;
1842 svec_init(&ucast_macs
);
1843 SHASH_FOR_EACH (node
, ucast_shash
) {
1844 struct vteprec_ucast_macs_local
*ucast_local
= node
->data
;
1845 struct vteprec_ucast_macs_remote
*ucast_remote
= node
->data
;
1846 struct vteprec_physical_locator
*ploc_cfg
;
1849 ploc_cfg
= local
? ucast_local
->locator
: ucast_remote
->locator
;
1851 entry
= xasprintf(" %s -> %s/%s", node
->name
,
1852 ploc_cfg
->encapsulation_type
, ploc_cfg
->dst_ip
);
1853 svec_add_nocopy(&ucast_macs
, entry
);
1855 ds_put_format(&ctx
->output
, "ucast-mac-%s\n", local
? "local" : "remote");
1856 output_sorted(&ucast_macs
, &ctx
->output
);
1857 ds_put_char(&ctx
->output
, '\n');
1858 svec_destroy(&ucast_macs
);
1860 svec_init(&mcast_macs
);
1861 SHASH_FOR_EACH (node
, mcast_shash
) {
1862 struct vtep_ctl_mcast_mac
*mcast_mac
= node
->data
;
1863 struct vtep_ctl_ploc
*ploc
;
1866 LIST_FOR_EACH (ploc
, locators_node
, &mcast_mac
->locators
) {
1867 entry
= xasprintf(" %s -> %s/%s", node
->name
,
1868 ploc
->ploc_cfg
->encapsulation_type
,
1869 ploc
->ploc_cfg
->dst_ip
);
1870 svec_add_nocopy(&mcast_macs
, entry
);
1873 ds_put_format(&ctx
->output
, "mcast-mac-%s\n", local
? "local" : "remote");
1874 output_sorted(&mcast_macs
, &ctx
->output
);
1875 ds_put_char(&ctx
->output
, '\n');
1876 svec_destroy(&mcast_macs
);
1880 cmd_list_local_macs(struct ctl_context
*ctx
)
1882 list_macs(ctx
, true);
1886 cmd_list_remote_macs(struct ctl_context
*ctx
)
1888 list_macs(ctx
, false);
1892 verify_managers(const struct vteprec_global
*vtep_global
)
1896 vteprec_global_verify_managers(vtep_global
);
1898 for (i
= 0; i
< vtep_global
->n_managers
; ++i
) {
1899 const struct vteprec_manager
*mgr
= vtep_global
->managers
[i
];
1901 vteprec_manager_verify_target(mgr
);
1906 pre_manager(struct ctl_context
*ctx
)
1908 ovsdb_idl_add_column(ctx
->idl
, &vteprec_global_col_managers
);
1909 ovsdb_idl_add_column(ctx
->idl
, &vteprec_manager_col_target
);
1913 cmd_get_manager(struct ctl_context
*ctx
)
1915 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1916 const struct vteprec_global
*vtep_global
= vtepctl_ctx
->vtep_global
;
1917 struct svec targets
;
1920 verify_managers(vtep_global
);
1922 /* Print the targets in sorted order for reproducibility. */
1923 svec_init(&targets
);
1925 for (i
= 0; i
< vtep_global
->n_managers
; i
++) {
1926 svec_add(&targets
, vtep_global
->managers
[i
]->target
);
1929 svec_sort_unique(&targets
);
1930 for (i
= 0; i
< targets
.n
; i
++) {
1931 ds_put_format(&ctx
->output
, "%s\n", targets
.names
[i
]);
1933 svec_destroy(&targets
);
1937 delete_managers(const struct vtep_ctl_context
*vtepctl_ctx
)
1939 const struct vteprec_global
*vtep_global
= vtepctl_ctx
->vtep_global
;
1942 /* Delete Manager rows pointed to by 'managers' column. */
1943 for (i
= 0; i
< vtep_global
->n_managers
; i
++) {
1944 vteprec_manager_delete(vtep_global
->managers
[i
]);
1947 /* Delete 'Manager' row refs in 'managers' column. */
1948 vteprec_global_set_managers(vtep_global
, NULL
, 0);
1952 cmd_del_manager(struct ctl_context
*ctx
)
1954 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1955 const struct vteprec_global
*vtep_global
= vtepctl_ctx
->vtep_global
;
1957 verify_managers(vtep_global
);
1958 delete_managers(vtepctl_ctx
);
1962 insert_managers(struct vtep_ctl_context
*vtepctl_ctx
, char *targets
[], size_t n
)
1964 struct vteprec_manager
**managers
;
1967 /* Insert each manager in a new row in Manager table. */
1968 managers
= xmalloc(n
* sizeof *managers
);
1969 for (i
= 0; i
< n
; i
++) {
1970 if (stream_verify_name(targets
[i
]) && pstream_verify_name(targets
[i
])) {
1971 VLOG_WARN("target type \"%s\" is possibly erroneous", targets
[i
]);
1973 managers
[i
] = vteprec_manager_insert(vtepctl_ctx
->base
.txn
);
1974 vteprec_manager_set_target(managers
[i
], targets
[i
]);
1977 /* Store uuids of new Manager rows in 'managers' column. */
1978 vteprec_global_set_managers(vtepctl_ctx
->vtep_global
, managers
, n
);
1983 cmd_set_manager(struct ctl_context
*ctx
)
1985 struct vtep_ctl_context
*vtepctl_ctx
= vtep_ctl_context_cast(ctx
);
1986 const size_t n
= ctx
->argc
- 1;
1988 verify_managers(vtepctl_ctx
->vtep_global
);
1989 delete_managers(vtepctl_ctx
);
1990 insert_managers(vtepctl_ctx
, &ctx
->argv
[1], n
);
1993 /* Parameter commands. */
1994 static const struct ctl_table_class tables
[] = {
1995 {&vteprec_table_global
,
1996 {{&vteprec_table_global
, NULL
, NULL
},
1997 {NULL
, NULL
, NULL
}}},
1999 {&vteprec_table_logical_binding_stats
,
2000 {{NULL
, NULL
, NULL
},
2001 {NULL
, NULL
, NULL
}}},
2003 {&vteprec_table_logical_switch
,
2004 {{&vteprec_table_logical_switch
, &vteprec_logical_switch_col_name
, NULL
},
2005 {NULL
, NULL
, NULL
}}},
2007 {&vteprec_table_ucast_macs_local
,
2008 {{NULL
, NULL
, NULL
},
2009 {NULL
, NULL
, NULL
}}},
2011 {&vteprec_table_ucast_macs_remote
,
2012 {{NULL
, NULL
, NULL
},
2013 {NULL
, NULL
, NULL
}}},
2015 {&vteprec_table_mcast_macs_local
,
2016 {{NULL
, NULL
, NULL
},
2017 {NULL
, NULL
, NULL
}}},
2019 {&vteprec_table_mcast_macs_remote
,
2020 {{NULL
, NULL
, NULL
},
2021 {NULL
, NULL
, NULL
}}},
2023 {&vteprec_table_manager
,
2024 {{&vteprec_table_manager
, &vteprec_manager_col_target
, NULL
},
2025 {NULL
, NULL
, NULL
}}},
2027 {&vteprec_table_physical_locator
,
2028 {{NULL
, NULL
, NULL
},
2029 {NULL
, NULL
, NULL
}}},
2031 {&vteprec_table_physical_locator_set
,
2032 {{NULL
, NULL
, NULL
},
2033 {NULL
, NULL
, NULL
}}},
2035 {&vteprec_table_physical_port
,
2036 {{&vteprec_table_physical_port
, &vteprec_physical_port_col_name
, NULL
},
2037 {NULL
, NULL
, NULL
}}},
2039 {&vteprec_table_physical_switch
,
2040 {{&vteprec_table_physical_switch
, &vteprec_physical_switch_col_name
, NULL
},
2041 {NULL
, NULL
, NULL
}}},
2043 {&vteprec_table_tunnel
,
2044 {{NULL
, NULL
, NULL
},
2045 {NULL
, NULL
, NULL
}}},
2047 {&vteprec_table_logical_router
,
2048 {{&vteprec_table_logical_router
, &vteprec_logical_router_col_name
, NULL
},
2049 {NULL
, NULL
, NULL
}}},
2051 {&vteprec_table_arp_sources_local
,
2052 {{NULL
, NULL
, NULL
},
2053 {NULL
, NULL
, NULL
}}},
2055 {&vteprec_table_arp_sources_remote
,
2056 {{NULL
, NULL
, NULL
},
2057 {NULL
, NULL
, NULL
}}},
2059 {NULL
, {{NULL
, NULL
, NULL
}, {NULL
, NULL
, NULL
}}}
2064 vtep_ctl_context_init_command(struct vtep_ctl_context
*vtepctl_ctx
,
2065 struct ctl_command
*command
)
2067 ctl_context_init_command(&vtepctl_ctx
->base
, command
);
2068 vtepctl_ctx
->verified_ports
= false;
2073 vtep_ctl_context_init(struct vtep_ctl_context
*vtepctl_ctx
,
2074 struct ctl_command
*command
,
2075 struct ovsdb_idl
*idl
, struct ovsdb_idl_txn
*txn
,
2076 const struct vteprec_global
*vtep_global
,
2077 struct ovsdb_symbol_table
*symtab
)
2079 ctl_context_init(&vtepctl_ctx
->base
, command
, idl
, txn
, symtab
,
2080 vtep_ctl_context_invalidate_cache
);
2082 vtepctl_ctx
->verified_ports
= false;
2084 vtepctl_ctx
->vtep_global
= vtep_global
;
2085 vtepctl_ctx
->cache_valid
= false;
2089 vtep_ctl_context_done_command(struct vtep_ctl_context
*vtepctl_ctx
,
2090 struct ctl_command
*command
)
2092 ctl_context_done_command(&vtepctl_ctx
->base
, command
);
2096 vtep_ctl_context_done(struct vtep_ctl_context
*vtepctl_ctx
,
2097 struct ctl_command
*command
)
2099 ctl_context_done(&vtepctl_ctx
->base
, command
);
2103 run_prerequisites(struct ctl_command
*commands
, size_t n_commands
,
2104 struct ovsdb_idl
*idl
)
2106 struct ctl_command
*c
;
2108 ovsdb_idl_add_table(idl
, &vteprec_table_global
);
2109 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2110 if (c
->syntax
->prerequisites
) {
2111 struct vtep_ctl_context vtepctl_ctx
;
2113 ds_init(&c
->output
);
2116 vtep_ctl_context_init(&vtepctl_ctx
, c
, idl
, NULL
, NULL
, NULL
);
2117 (c
->syntax
->prerequisites
)(&vtepctl_ctx
.base
);
2118 vtep_ctl_context_done(&vtepctl_ctx
, c
);
2120 ovs_assert(!c
->output
.string
);
2121 ovs_assert(!c
->table
);
2127 do_vtep_ctl(const char *args
, struct ctl_command
*commands
,
2128 size_t n_commands
, struct ovsdb_idl
*idl
)
2130 struct ovsdb_idl_txn
*txn
;
2131 const struct vteprec_global
*vtep_global
;
2132 enum ovsdb_idl_txn_status status
;
2133 struct ovsdb_symbol_table
*symtab
;
2134 struct vtep_ctl_context vtepctl_ctx
;
2135 struct ctl_command
*c
;
2136 struct shash_node
*node
;
2139 txn
= the_idl_txn
= ovsdb_idl_txn_create(idl
);
2141 ovsdb_idl_txn_set_dry_run(txn
);
2144 ovsdb_idl_txn_add_comment(txn
, "vtep-ctl: %s", args
);
2146 vtep_global
= vteprec_global_first(idl
);
2148 /* XXX add verification that table is empty */
2149 vtep_global
= vteprec_global_insert(txn
);
2152 symtab
= ovsdb_symbol_table_create();
2153 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2154 ds_init(&c
->output
);
2157 vtep_ctl_context_init(&vtepctl_ctx
, NULL
, idl
, txn
, vtep_global
, symtab
);
2158 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2159 vtep_ctl_context_init_command(&vtepctl_ctx
, c
);
2160 if (c
->syntax
->run
) {
2161 (c
->syntax
->run
)(&vtepctl_ctx
.base
);
2163 vtep_ctl_context_done_command(&vtepctl_ctx
, c
);
2165 if (vtepctl_ctx
.base
.try_again
) {
2166 vtep_ctl_context_done(&vtepctl_ctx
, NULL
);
2170 vtep_ctl_context_done(&vtepctl_ctx
, NULL
);
2172 SHASH_FOR_EACH (node
, &symtab
->sh
) {
2173 struct ovsdb_symbol
*symbol
= node
->data
;
2174 if (!symbol
->created
) {
2175 ctl_fatal("row id \"%s\" is referenced but never created "
2176 "(e.g. with \"-- --id=%s create ...\")",
2177 node
->name
, node
->name
);
2179 if (!symbol
->strong_ref
) {
2180 if (!symbol
->weak_ref
) {
2181 VLOG_WARN("row id \"%s\" was created but no reference to it "
2182 "was inserted, so it will not actually appear in "
2183 "the database", node
->name
);
2185 VLOG_WARN("row id \"%s\" was created but only a weak "
2186 "reference to it was inserted, so it will not "
2187 "actually appear in the database", node
->name
);
2192 status
= ovsdb_idl_txn_commit_block(txn
);
2193 if (status
== TXN_UNCHANGED
|| status
== TXN_SUCCESS
) {
2194 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2195 if (c
->syntax
->postprocess
) {
2196 vtep_ctl_context_init(&vtepctl_ctx
, c
, idl
, txn
, vtep_global
, symtab
);
2197 (c
->syntax
->postprocess
)(&vtepctl_ctx
.base
);
2198 vtep_ctl_context_done(&vtepctl_ctx
, c
);
2202 error
= xstrdup(ovsdb_idl_txn_get_error(txn
));
2203 ovsdb_idl_txn_destroy(txn
);
2204 txn
= the_idl_txn
= NULL
;
2207 case TXN_UNCOMMITTED
:
2208 case TXN_INCOMPLETE
:
2212 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
2213 ctl_fatal("transaction aborted");
2223 ctl_fatal("transaction error: %s", error
);
2225 case TXN_NOT_LOCKED
:
2226 /* Should not happen--we never call ovsdb_idl_set_lock(). */
2227 ctl_fatal("database not locked");
2234 ovsdb_symbol_table_destroy(symtab
);
2236 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2237 struct ds
*ds
= &c
->output
;
2240 table_print(c
->table
, &table_style
);
2241 } else if (oneline
) {
2245 for (j
= 0; j
< ds
->length
; j
++) {
2246 int ch
= ds
->string
[j
];
2249 fputs("\\n", stdout
);
2253 fputs("\\\\", stdout
);
2262 fputs(ds_cstr(ds
), stdout
);
2264 ds_destroy(&c
->output
);
2265 table_destroy(c
->table
);
2268 shash_destroy_free_data(&c
->options
);
2272 ovsdb_idl_destroy(idl
);
2277 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
2278 * resources and return so that the caller can try again. */
2280 ovsdb_idl_txn_abort(txn
);
2281 ovsdb_idl_txn_destroy(txn
);
2283 ovsdb_symbol_table_destroy(symtab
);
2284 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
2285 ds_destroy(&c
->output
);
2286 table_destroy(c
->table
);
2292 static const struct ctl_command_syntax vtep_commands
[] = {
2293 /* Physical Switch commands. */
2294 {"add-ps", 1, 1, NULL
, pre_get_info
, cmd_add_ps
, NULL
, "--may-exist", RW
},
2295 {"del-ps", 1, 1, NULL
, pre_get_info
, cmd_del_ps
, NULL
, "--if-exists", RW
},
2296 {"list-ps", 0, 0, NULL
, pre_get_info
, cmd_list_ps
, NULL
, "", RO
},
2297 {"ps-exists", 1, 1, NULL
, pre_get_info
, cmd_ps_exists
, NULL
, "", RO
},
2299 /* Port commands. */
2300 {"list-ports", 1, 1, NULL
, pre_get_info
, cmd_list_ports
, NULL
, "", RO
},
2301 {"add-port", 2, 2, NULL
, pre_get_info
, cmd_add_port
, NULL
, "--may-exist",
2303 {"del-port", 2, 2, NULL
, pre_get_info
, cmd_del_port
, NULL
, "--if-exists",
2306 /* Logical Switch commands. */
2307 {"add-ls", 1, 1, NULL
, pre_get_info
, cmd_add_ls
, NULL
, "--may-exist", RW
},
2308 {"del-ls", 1, 1, NULL
, pre_get_info
, cmd_del_ls
, NULL
, "--if-exists", RW
},
2309 {"list-ls", 0, 0, NULL
, pre_get_info
, cmd_list_ls
, NULL
, "", RO
},
2310 {"ls-exists", 1, 1, NULL
, pre_get_info
, cmd_ls_exists
, NULL
, "", RO
},
2311 {"list-bindings", 2, 2, NULL
, pre_get_info
, cmd_list_bindings
, NULL
, "", RO
},
2312 {"bind-ls", 4, 4, NULL
, pre_get_info
, cmd_bind_ls
, NULL
, "", RO
},
2313 {"unbind-ls", 3, 3, NULL
, pre_get_info
, cmd_unbind_ls
, NULL
, "", RO
},
2315 /* MAC binding commands. */
2316 {"add-ucast-local", 3, 4, NULL
, pre_get_info
, cmd_add_ucast_local
, NULL
,
2318 {"del-ucast-local", 2, 2, NULL
, pre_get_info
, cmd_del_ucast_local
, NULL
,
2320 {"add-mcast-local", 3, 4, NULL
, pre_get_info
, cmd_add_mcast_local
, NULL
,
2322 {"del-mcast-local", 3, 4, NULL
, pre_get_info
, cmd_del_mcast_local
, NULL
,
2324 {"clear-local-macs", 1, 1, NULL
, pre_get_info
, cmd_clear_local_macs
, NULL
,
2326 {"list-local-macs", 1, 1, NULL
, pre_get_info
, cmd_list_local_macs
, NULL
,
2328 {"add-ucast-remote", 3, 4, NULL
, pre_get_info
, cmd_add_ucast_remote
, NULL
,
2330 {"del-ucast-remote", 2, 2, NULL
, pre_get_info
, cmd_del_ucast_remote
, NULL
,
2332 {"add-mcast-remote", 3, 4, NULL
, pre_get_info
, cmd_add_mcast_remote
, NULL
,
2334 {"del-mcast-remote", 3, 4, NULL
, pre_get_info
, cmd_del_mcast_remote
, NULL
,
2336 {"clear-remote-macs", 1, 1, NULL
, pre_get_info
, cmd_clear_remote_macs
, NULL
,
2338 {"list-remote-macs", 1, 1, NULL
, pre_get_info
, cmd_list_remote_macs
, NULL
,
2341 /* Manager commands. */
2342 {"get-manager", 0, 0, NULL
, pre_manager
, cmd_get_manager
, NULL
, "", RO
},
2343 {"del-manager", 0, 0, NULL
, pre_manager
, cmd_del_manager
, NULL
, "", RW
},
2344 {"set-manager", 1, INT_MAX
, NULL
, pre_manager
, cmd_set_manager
, NULL
, "",
2347 {NULL
, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, RO
},
2350 /* Registers vsctl and common db commands. */
2352 vtep_ctl_cmd_init(void)
2354 ctl_init(tables
, cmd_show_tables
, vtep_ctl_exit
);
2355 ctl_register_commands(vtep_commands
);