Signed-off-by: nickcooper-zhangtonghao <nickcooper-zhangtong...@opencloud.tech> --- ovn/ovn-nb.ovsschema | 5 +- ovn/ovn-nb.xml | 6 ++ ovn/utilities/ovn-nbctl.c | 163 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 3 deletions(-)
diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema index 456ae98..87ce15f 100644 --- a/ovn/ovn-nb.ovsschema +++ b/ovn/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", "version": "5.3.1", - "cksum": "1921908091 9353", + "cksum": "360001470 9398", "tables": { "NB_Global": { "columns": { @@ -92,6 +92,7 @@ "isRoot": true}, "Load_Balancer": { "columns": { + "name": {"type": "string"}, "vips": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, @@ -102,7 +103,7 @@ "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, - "isRoot": true}, + "isRoot": false}, "ACL": { "columns": { "priority": {"type": {"key": {"type": "integer", diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index 5719e74..c3666f5 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -660,6 +660,12 @@ Each row represents one load balancer. </p> + <column name="name"> + A name for the load balancer. This must be unique among all load balancers. + This name has no special meaning or purpose other than to provide convenience + for human interaction with the ovn-nb database. + </column> + <column name="vips"> <p> A map of virtual IPv4 addresses (and an optional port number with diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index d6d64ea..fc02918 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -331,6 +331,13 @@ ACL commands:\n\ remove ACLs from SWITCH\n\ acl-list SWITCH print ACLs for SWITCH\n\ \n\ +LB commands:\n\ + lb-add SWITCH LB VIP[:PORT] IP[:PORT]... [PROTOCOL]\n\ + add a load-balancer to SWITCH\n\ + lb-del SWITCH [LB]\n\ + remove load-balancers from SWITCH\n\ + lb-list SWITCH [LB] print load-balancers for SWITCH\n\ +\n\ Logical switch port commands:\n\ lsp-add SWITCH PORT add logical port PORT on SWITCH\n\ lsp-add SWITCH PORT PARENT TAG\n\ @@ -1315,7 +1322,154 @@ nbctl_acl_del(struct ctl_context *ctx) } } } - + +static void +nbctl_lb_add(struct ctl_context *ctx) +{ + const struct nbrec_logical_switch *ls; + const char *lb_name = ctx->argv[2]; + const char *lb_vip = ctx->argv[3]; + const char *lb_ips = ctx->argv[4]; + + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true); + + const char *lb_proto; + if (ctx->argc == 5) { + /* default protocol.*/ + lb_proto = "tcp"; + } else { + lb_proto = ctx->argv[5]; + /* Validate protocol. */ + if (strcmp(lb_proto, "tcp") && strcmp(lb_proto, "udp")) { + ctl_fatal("%s: protocol must be one of \"tcp\", \"udp\".", lb_proto); + } + } + + bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; + for (int i = 0; i < ls->n_load_balancer; i++) { + const struct nbrec_load_balancer *lb + = ls->load_balancer[i]; + + if (strcmp(lb->name, lb_name)) { + continue; + } + + if (!may_exist) { + ctl_fatal("%s: a load balancer with this name already exists", lb_name); + } + + nbrec_logical_switch_verify_load_balancer(ls); + nbrec_load_balancer_verify_protocol(lb); + nbrec_load_balancer_verify_vips(lb); + nbrec_load_balancer_set_protocol(lb, lb_proto); + + struct smap vips = SMAP_INITIALIZER(&vips); + smap_add(&vips, lb_vip, lb_ips); + nbrec_load_balancer_set_vips(lb, &vips); + smap_destroy(&vips); + + return; + } + + /* Create the load balancer. */ + struct nbrec_load_balancer *lb = nbrec_load_balancer_insert(ctx->txn); + nbrec_load_balancer_set_name(lb, lb_name); + nbrec_load_balancer_set_protocol(lb, lb_proto); + + struct smap vips = SMAP_INITIALIZER(&vips); + smap_add(&vips, lb_vip, lb_ips); + nbrec_load_balancer_set_vips(lb, &vips); + smap_destroy(&vips); + + /* Insert the load balancer into the logical switch. */ + nbrec_logical_switch_verify_acls(ls); + struct nbrec_load_balancer **new_lbs + = xmalloc(sizeof *new_lbs * (ls->n_load_balancer + 1)); + + memcpy(new_lbs, ls->load_balancer, sizeof *new_lbs * ls->n_load_balancer); + new_lbs[ls->n_load_balancer] = lb; + nbrec_logical_switch_set_load_balancer(ls, new_lbs, ls->n_load_balancer + 1); + free(new_lbs); +} + +static void +nbctl_lb_del(struct ctl_context *ctx) +{ + const char *lb_name = ctx->argv[2]; + const struct nbrec_logical_switch *ls; + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true); + + if (ctx->argc == 2) { + /* If load-balancer is not specified, delete + * all load-balancers. */ + nbrec_logical_switch_verify_load_balancer(ls); + nbrec_logical_switch_set_load_balancer(ls, NULL, 0); + return; + } + + for (size_t i = 0; i < ls->n_load_balancer; i++) { + const struct nbrec_load_balancer *lb + = ls->load_balancer[i]; + + if (strcmp(lb->name, lb_name)) { + continue; + } + + /* Remove the matching rule. */ + struct nbrec_load_balancer **new_lbs + = xmemdup(ls->load_balancer, sizeof *new_lbs * ls->n_load_balancer); + new_lbs[i] = ls->load_balancer[ls->n_load_balancer - 1]; + nbrec_logical_switch_verify_load_balancer(ls); + nbrec_logical_switch_set_load_balancer(ls, new_lbs, + ls->n_load_balancer - 1); + free(new_lbs); + return; + } + + bool must_exist = !shash_find(&ctx->options, "--if-exists"); + if (must_exist) { + ctl_fatal("load balancer %s is not part of any logical switch.", + lb_name); + } +} + +static void +nbctl_lb_list(struct ctl_context *ctx) +{ + const struct nbrec_logical_switch *ls; + + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true); + + struct smap lbs = SMAP_INITIALIZER(&lbs); + for (int i = 0; i < ls->n_load_balancer; i++) { + const struct nbrec_load_balancer *lb + = ls->load_balancer[i]; + if (ctx->argc == 3 && strcmp(lb->name, ctx->argv[2])) { + continue; + } + + const struct smap_node **nodes = smap_sort(&lb->vips); + if (nodes) { + const struct smap_node *node = nodes[0]; + smap_add_format(&lbs, lb->name, "%-10.8s %-5s %-20s %s", + lb->name, lb->protocol, node->key, node->value); + free(nodes); + } + } + + const struct smap_node **nodes = smap_sort(&lbs); + ds_put_format(&ctx->output, + "Logical Switch: %s\n" + "%-10.8s %-5s %-20s IPs\n", + ls->name, "LB", "PROTO", "VIP"); + for (size_t i = 0; i < smap_count(&lbs); i++) { + const struct smap_node *node = nodes[i]; + ds_put_format(&ctx->output, "%s\n", node->value); + } + smap_destroy(&lbs); + free(nodes); +} + static void nbctl_lr_add(struct ctl_context *ctx) { @@ -2420,6 +2574,13 @@ static const struct ctl_command_syntax nbctl_commands[] = { nbctl_acl_del, NULL, "", RW }, { "acl-list", 1, 1, "SWITCH", NULL, nbctl_acl_list, NULL, "", RO }, + /* load balancer commands. */ + { "lb-add", 4, 5, "SWITCH LB VIP[:PORT] IP[:PORT]... [PROTOCOL]", NULL, + nbctl_lb_add, NULL, "--may-exist", RW }, + { "lb-del", 1, 2, "SWITCH [LB]", NULL, + nbctl_lb_del, NULL, "--if-exists", RW }, + { "lb-list", 1, 2, "SWITCH [LB]", NULL, nbctl_lb_list, NULL, "", RO }, + /* logical switch port commands. */ { "lsp-add", 2, 4, "SWITCH PORT [PARENT] [TAG]", NULL, nbctl_lsp_add, NULL, "--may-exist", RW }, -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev