+static struct vtep_ctl_lrouter *
+find_lrouter(struct vtep_ctl_context *vtepctl_ctx,
+ const char *name, bool must_exist)
+{
+ struct vtep_ctl_lrouter *lr;
+
+ ovs_assert(vtepctl_ctx->cache_valid);
+
+ lr = shash_find_data(&vtepctl_ctx->lrouters, name);
+ if (must_exist && !lr) {
+ ctl_fatal("no logical router named %s", name);
+ }
+ return lr;
+}
+
+static void
+cmd_add_lr(struct ctl_context *ctx)
+{
+ struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
+ const char *lr_name = ctx->argv[1];
+ bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
+ struct vteprec_logical_router *lr;
+
+ vtep_ctl_context_populate_cache(ctx);
+ if (find_lrouter(vtepctl_ctx, lr_name, false)) {
+ if (!may_exist) {
+ ctl_fatal("cannot create logical router %s because it "
+ "already exists", lr_name);
+ }
+ return;
+ }
+
+ lr = vteprec_logical_router_insert(ctx->txn);
+ vteprec_logical_router_set_name(lr, lr_name);
+
+ vtep_ctl_context_invalidate_cache(ctx);
+}
+
+static void
+del_lrouter(struct vtep_ctl_context *vtepctl_ctx, struct vtep_ctl_lrouter *lr)
+{
+ del_cached_lrouter(vtepctl_ctx, lr);
+}
+
+static void
+cmd_del_lr(struct ctl_context *ctx)
+{
+ struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
+ struct vtep_ctl_lrouter *lr;
+
+ vtep_ctl_context_populate_cache(ctx);
+ lr = find_lrouter(vtepctl_ctx, ctx->argv[1], must_exist);
+ if (lr) {
+ del_lrouter(vtepctl_ctx, lr);
+ }
+}
+
+static void
+cmd_list_lr(struct ctl_context *ctx)
+{
+ struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
+ struct shash_node *node;
+ struct svec lrouters;
+
+ vtep_ctl_context_populate_cache(ctx);
+
+ svec_init(&lrouters);
+ SHASH_FOR_EACH (node, &vtepctl_ctx->lrouters) {
+ struct vtep_ctl_lrouter *lr = node->data;
+
+ svec_add(&lrouters, lr->name);
+ }
+ output_sorted(&lrouters, &ctx->output);
+ svec_destroy(&lrouters);
+}
+
+static void
+cmd_lr_exists(struct ctl_context *ctx)
+{
+ struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
+
+ vtep_ctl_context_populate_cache(ctx);
+ if (!find_lrouter(vtepctl_ctx, ctx->argv[1], false)) {
+ vtep_ctl_exit(2);
+ }
+}
+