Added commands to add, delete and list transit routers.
$ ovn-ic-nbctl tr-add tr0
$ ovn-ic-nbctl tr-del tr0
$ ovn-ic-nbctl tr-list
Added commands to add and delete a transit router port.
$ ovn-ic-nbctl trp-add tr0 tr0-p0 00:00:00:11:22:00 192.168.10.10/24
192.168.10.20/24 chassis=ovn-chassis-1
$ ovn-ic-nbctl trp-del tr0-p0
Reported-at: https://issues.redhat.com/browse/FDP-1477
Signed-off-by: Mairtin O'Loingsigh <[email protected]>
---
utilities/ovn-ic-nbctl.c | 266 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 264 insertions(+), 2 deletions(-)
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 5819192fe..740c75bf1 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -337,6 +337,14 @@ Transit switch commands:\n\
ts-del SWITCH delete SWITCH\n\
ts-list print all transit switches\n\
\n\
+Transit router commands:\n\
+ tr-add ROUTER create a transit router named ROUTER\n\
+ tr-del ROUTER delete ROUTER\n\
+ tr-list print all transit routers\n\
+ trp-add ROUTER PORT MAC [NETWORK]...[chassis=CHASSIS]\n\
+ add a transit router PORT\n\
+ trp-del PORT delete a transit router PORT\n\
+\n\
Connection commands:\n\
get-connection print the connections\n\
del-connection delete the connections\n\
@@ -397,10 +405,20 @@ struct ic_nbctl_context {
static struct cmd_show_table cmd_show_tables[] = {
{&icnbrec_table_transit_switch,
&icnbrec_transit_switch_col_name,
- {NULL},
+ {NULL, NULL, NULL},
+ {NULL, NULL, NULL}},
+
+ {&icnbrec_table_transit_router,
+ &icnbrec_transit_router_col_name,
+ {NULL, NULL, NULL},
+ {NULL, NULL, NULL}},
+
+ {&icnbrec_table_transit_router_port,
+ &icnbrec_transit_router_port_col_name,
+ {&icnbrec_transit_router_port_col_nb_ic_uuid, NULL, NULL},
{NULL, NULL, NULL}},
- {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}},
+ {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}}
};
static void
@@ -507,6 +525,228 @@ ic_nbctl_ts_list(struct ctl_context *ctx)
smap_destroy(&switches);
free(nodes);
}
+
+static void
+ic_nbctl_tr_add(struct ctl_context *ctx)
+{
+ if (!ovsdb_idl_server_has_table(ctx->idl, &icnbrec_table_transit_router)) {
+ VLOG_WARN("icnbrec_table_transit_router missing");
+ }
+
+ const char *tr_name = ctx->argv[1];
+ bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
+
+ const struct icnbrec_transit_router *tr;
+ ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->idl) {
+ if (!strcmp(tr->name, tr_name)) {
+ if (may_exist) {
+ return;
+ }
+
+ ctl_error(ctx, "%s: a transit router with this name already "
+ "exists", tr_name);
+ return;
+ }
+
+ }
+ tr = icnbrec_transit_router_insert(ctx->txn);
+
+ icnbrec_transit_router_set_name(tr, tr_name);
+}
+
+static char *
+tr_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist,
+ const struct icnbrec_transit_router **tr_p)
+{
+ const struct icnbrec_transit_router *tr = NULL;
+ *tr_p = NULL;
+
+ struct uuid tr_uuid;
+ bool is_uuid = uuid_from_string(&tr_uuid, id);
+ if (is_uuid) {
+ tr = icnbrec_transit_router_get_for_uuid(ctx->idl, &tr_uuid);
+ }
+
+ if (!tr) {
+ const struct icnbrec_transit_router *iter;
+
+ ICNBREC_TRANSIT_ROUTER_FOR_EACH (iter, ctx->idl) {
+ if (!strcmp(iter->name, id)) {
+ tr = iter;
+ break;
+ }
+ }
+ }
+
+ if (!tr && must_exist) {
+ return xasprintf("%s: router %s not found",
+ id, is_uuid ? "UUID" : "name");
+ }
+
+ *tr_p = tr;
+ return NULL;
+}
+
+static void
+ic_nbctl_tr_del(struct ctl_context *ctx)
+{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
+ const char *id = ctx->argv[1];
+ const struct icnbrec_transit_router *tr = NULL;
+
+ char *error = tr_by_name_or_uuid(ctx, id, must_exist, &tr);
+ if (error) {
+ ctx->error = error;
+ return;
+ }
+
+ if (!tr) {
+ return;
+ }
+
+ icnbrec_transit_router_delete(tr);
+}
+
+static void
+ic_nbctl_trp_del(struct ctl_context *ctx)
+{
+ const char *port = ctx->argv[1];
+ const struct icnbrec_transit_router_port *trp = NULL;
+
+ const struct icnbrec_transit_router_port *iter;
+
+ ICNBREC_TRANSIT_ROUTER_PORT_FOR_EACH (iter, ctx->idl) {
+ if (!strcmp(iter->name, port)) {
+ trp = iter;
+ break;
+ }
+
+ }
+
+ if (!trp) {
+ ctx->error = xasprintf("%s: router port not found", port);
+ return;
+ }
+
+ icnbrec_transit_router_port_delete(trp);
+}
+
+static void
+ic_nbctl_tr_list(struct ctl_context *ctx)
+{
+ const struct icnbrec_transit_router *tr;
+ struct smap routers;
+
+ smap_init(&routers);
+ ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->idl) {
+ smap_add_format(&routers, tr->name, UUID_FMT " (%s)",
+ UUID_ARGS(&tr->header_.uuid), tr->name);
+ }
+ const struct smap_node **nodes = smap_sort(&routers);
+ for (size_t i = 0; i < smap_count(&routers); i++) {
+ const struct smap_node *node = nodes[i];
+ ds_put_format(&ctx->output, "%s\n", node->value);
+ }
+ smap_destroy(&routers);
+ free(nodes);
+}
+
+static void
+ic_nbctl_trp_add(struct ctl_context *ctx)
+{
+ const char *tr_name = ctx->argv[1];
+ const char *trp_name = ctx->argv[2];
+ const char *mac = ctx->argv[3];
+ const char **networks = (const char **) &ctx->argv[4];
+ bool found = false;
+ const struct icnbrec_transit_router *tr;
+ ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->idl) {
+ if (!strcmp(tr->name, tr_name)) {
+ found = true;
+ break;
+ }
+
+ }
+
+ if (!found) {
+ ctl_error(ctx, "%s: transit router does not exist.", tr_name);
+ return;
+ }
+
+ found = false;
+ const struct icnbrec_transit_router_port *trp;
+ ICNBREC_TRANSIT_ROUTER_PORT_FOR_EACH (trp, ctx->idl) {
+ if (!strcmp(trp->name, trp_name)) {
+ found = true;
+ break;
+ }
+
+ }
+
+ if (found) {
+ ctl_error(ctx, "%s: a transit router port with this name already "
+ "exists.", trp_name);
+ return;
+
+ }
+
+ struct eth_addr ea;
+ if (!eth_addr_from_string(mac, &ea)) {
+ ctl_error(ctx, "%s: MAC address is invalid.", mac);
+ return;
+ }
+
+ /* Parse networks*/
+ int n_networks = ctx->argc - 4;
+ for (int i = 4; i < ctx->argc; i++) {
+ if (strchr(ctx->argv[i], '=')) {
+ n_networks = i - 4;
+ break;
+ }
+
+ }
+
+ char **settings = (char **) &ctx->argv[n_networks + 4];
+ int n_settings = ctx->argc - 4 - n_networks;
+
+ for (int i = 0; i < n_networks; i++) {
+ ovs_be32 ipv4;
+ unsigned int plen;
+ char *error;
+ error = ip_parse_cidr(networks[i], &ipv4, &plen);
+ if (error) {
+ free(error);
+ struct in6_addr ipv6;
+ error = ipv6_parse_cidr(networks[i], &ipv6, &plen);
+ if (error) {
+ free(error);
+ ctl_error(ctx, "%s: invalid network address: %s", trp_name,
+ networks[i]);
+ return;
+ }
+
+ }
+
+ }
+
+ trp = icnbrec_transit_router_port_insert(ctx->txn);
+ icnbrec_transit_router_port_set_transit_router(trp, tr_name);
+ icnbrec_transit_router_port_set_name(trp, trp_name);
+ icnbrec_transit_router_port_set_mac(trp, mac);
+ icnbrec_transit_router_port_set_nb_ic_uuid(trp, tr->header_.uuid);
+ icnbrec_transit_router_port_set_networks(trp, networks, n_networks);
+
+ for (int i = 0; i < n_settings; i++) {
+ char *error = ctl_set_column("Transit_Router_Port", &trp->header_,
+ settings[i], ctx->symtab);
+ if (error) {
+ ctx->error = error;
+ return;
+ }
+
+ }
+}
+
static void
verify_connections(struct ctl_context *ctx)
{
@@ -714,6 +954,15 @@ cmd_set_ssl(struct ctl_context *ctx)
static const struct ctl_table_class tables[ICNBREC_N_TABLES] = {
[ICNBREC_TABLE_TRANSIT_SWITCH].row_ids[0] =
{&icnbrec_transit_switch_col_name, NULL, NULL},
+
+ [ICNBREC_TABLE_TRANSIT_ROUTER].row_ids[0] =
+ {&icnbrec_transit_router_col_name, NULL, NULL},
+
+ [ICNBREC_TABLE_TRANSIT_ROUTER_PORT].row_ids =
+ {{&icnbrec_transit_router_port_col_name, NULL, NULL},
+ {&icnbrec_transit_router_port_col_nb_ic_uuid, NULL, NULL},
+ {&icnbrec_transit_router_port_col_mac, NULL, NULL},
+ {&icnbrec_transit_router_port_col_transit_router, NULL, NULL}},
};
@@ -1010,11 +1259,24 @@ ic_nbctl_exit(int status)
static const struct ctl_command_syntax ic_nbctl_commands[] = {
{ "init", 0, 0, "", NULL, ic_nbctl_init, NULL, "", RW },
{ "sync", 0, 0, "", ic_nbctl_pre_sync, NULL, NULL, "", RO },
+
/* transit switch commands. */
{ "ts-add", 1, 1, "SWITCH", NULL, ic_nbctl_ts_add, NULL, "--may-exist", RW
},
{ "ts-del", 1, 1, "SWITCH", NULL, ic_nbctl_ts_del, NULL, "--if-exists", RW
},
{ "ts-list", 0, 0, "", NULL, ic_nbctl_ts_list, NULL, "", RO },
+ /* transit router commands. */
+ { "tr-add", 1, 1, "ROUTER", NULL, ic_nbctl_tr_add, NULL, "--may-exist",
+ RW },
+ { "tr-del", 1, 1, "ROUTER", NULL, ic_nbctl_tr_del, NULL, "--if-exists",
+ RW },
+ { "tr-list", 0, 0, "", NULL, ic_nbctl_tr_list, NULL, "", RO },
+ { "trp-add", 4, INT_MAX,
+ "ROUTER PORT MAC [NETWORK]...[COLUMN[:KEY]=VALUE]...",
+ NULL, ic_nbctl_trp_add, NULL, "--may-exist", RW },
+ { "trp-del", 1, 1, "PORT", NULL, ic_nbctl_trp_del, NULL, "--if-exists",
+ RW },
+
/* Connection commands. */
{"get-connection", 0, 0, "", pre_connection, cmd_get_connection, NULL, "",
RO},
--
2.50.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev