Skip to content

Commit

Permalink
Separate the ssl config of ovsdb from openflow
Browse files Browse the repository at this point in the history
modify the table of SSL to support 2 rows of SSL config belongs to ovsdb
and openflow for each
modify commands:
ovs-vsctl set-ssl
ovs-vsctl get-ssl
ovs-vsctl del-ssl
add a variable means the owner of components to support the SSL
management of ovsdb and openflow
  • Loading branch information
y30021871 committed Apr 2, 2022
1 parent b16270e commit 4340678
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 45 deletions.
23 changes: 14 additions & 9 deletions ovsdb/ovsdb-server.c
Expand Up @@ -876,13 +876,13 @@ parse_db_string_column(const struct shash *all_dbs,
}

static const char *
query_db_string(const struct shash *all_dbs, const char *name,
struct ds *errors)
query_db_ssl_string(const struct shash *all_dbs, const char *name, struct ds *errors)
{
if (!name || strncmp(name, "db:", 3)) {
return name;
} else {
const struct ovsdb_column *column;
const struct ovsdb_column *owner_column;
const struct ovsdb_table *table;
const struct ovsdb_row *row;
const struct db *db;
Expand All @@ -902,14 +902,19 @@ query_db_string(const struct shash *all_dbs, const char *name,
return NULL;
}

owner_column = ovsdb_table_schema_get_column(table->schema, OVSDB_SSL_OWNER_COLUMN);
if (!owner_column) {
return NULL;
}

HMAP_FOR_EACH (row, hmap_node, &table->rows) {
const struct ovsdb_datum *owner_datum;
const struct ovsdb_datum *datum;
size_t i;

datum = &row->fields[column->index];
for (i = 0; i < datum->n; i++) {
const char *key = json_string(datum->keys[i].s);
if (key[0]) {
if ((strcmp(owner_datum->keys[i].string, OVSDB_SSL_OWNER) == 0)) {
return key;
}
}
Expand Down Expand Up @@ -1321,11 +1326,11 @@ reconfigure_ssl(const struct shash *all_dbs)
const char *resolved_ssl_protocols;
const char *resolved_ssl_ciphers;

resolved_private_key = query_db_string(all_dbs, private_key_file, &errors);
resolved_certificate = query_db_string(all_dbs, certificate_file, &errors);
resolved_ca_cert = query_db_string(all_dbs, ca_cert_file, &errors);
resolved_ssl_protocols = query_db_string(all_dbs, ssl_protocols, &errors);
resolved_ssl_ciphers = query_db_string(all_dbs, ssl_ciphers, &errors);
resolved_private_key = query_db_ssl_string(all_dbs, private_key_file, &errors);
resolved_certificate = query_db_ssl_string(all_dbs, certificate_file, &errors);
resolved_ca_cert = query_db_ssl_string(all_dbs, ca_cert_file, &errors);
resolved_ssl_protocols = query_db_ssl_string(all_dbs, ssl_protocols, &errors);
resolved_ssl_ciphers = query_db_ssl_string(all_dbs, ssl_ciphers, &errors);

stream_ssl_set_key_and_cert(resolved_private_key, resolved_certificate);
stream_ssl_set_ca_cert_file(resolved_ca_cert, bootstrap_ca_cert);
Expand Down
3 changes: 3 additions & 0 deletions ovsdb/ovsdb.h
Expand Up @@ -127,4 +127,7 @@ struct ovsdb_error *ovsdb_snapshot(struct ovsdb *, bool trim_memory)

void ovsdb_replace(struct ovsdb *dst, struct ovsdb *src);

#define OVSDB_SSL_OWNER "ovsdb"
#define OVSDB_SSL_OWNER_COLUMN "owner"

#endif /* ovsdb/ovsdb.h */
120 changes: 90 additions & 30 deletions utilities/ovs-vsctl.c
Expand Up @@ -53,6 +53,8 @@
#include "table.h"
#include "timeval.h"
#include "util.h"
#include "ovsdb/ovsdb.h"
#include "vswitchd/bridge.h"

VLOG_DEFINE_THIS_MODULE(vsctl);

Expand Down Expand Up @@ -1073,7 +1075,7 @@ static void
pre_cmd_emer_reset(struct ctl_context *ctx)
{
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssls);

ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
Expand Down Expand Up @@ -1111,7 +1113,7 @@ cmd_emer_reset(struct ctl_context *ctx)

/* Reset the Open_vSwitch table. */
ovsrec_open_vswitch_set_manager_options(vsctl_ctx->ovs, NULL, 0);
ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
ovsrec_open_vswitch_set_ssls(vsctl_ctx->ovs, NULL, 0);

OVSREC_BRIDGE_FOR_EACH (br, idl) {
const char *hwaddr;
Expand Down Expand Up @@ -2362,11 +2364,19 @@ cmd_set_manager(struct ctl_context *ctx)
insert_managers(vsctl_ctx, &ctx->argv[1], n, &ctx->options);
}

static void check_ssl_owner(char *owner)
{
if ((strcmp(owner, OVSDB_SSL_OWNER) != 0) &&
(strcmp(owner, OPENFLOW_SSL_OWNER) != 0)) {
ctl_fatal("owner must be one of \"%s\", \"%s\"", OVSDB_SSL_OWNER, OPENFLOW_SSL_OWNER);
}
}

static void
pre_cmd_get_ssl(struct ctl_context *ctx)
{
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);

ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssls);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_owner);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_private_key);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_certificate);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_ca_cert);
Expand All @@ -2376,69 +2386,119 @@ pre_cmd_get_ssl(struct ctl_context *ctx)
static void
cmd_get_ssl(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;

ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
struct ovsrec_open_vswitch *ovs = vsctl_context_cast(ctx)->ovs;
struct ovsrec_ssl *ssl = NULL;
char *owner = ctx->argv[1];
check_ssl_owner(owner);

ovsrec_open_vswitch_verify_ssls(ovs);
for (size_t i = 0; i < ovs->n_ssls; i++) {
if (strcmp(ovs->ssls[i]->owner, owner) == 0) {
ssl = ovs->ssls[i];
break;
}
}


if (ssl) {
ovsrec_ssl_verify_owner(ssl);
ovsrec_ssl_verify_private_key(ssl);
ovsrec_ssl_verify_certificate(ssl);
ovsrec_ssl_verify_ca_cert(ssl);
ovsrec_ssl_verify_bootstrap_ca_cert(ssl);


ds_put_format(&ctx->output, "Owner: %s\n", ssl->owner);
ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
ds_put_format(&ctx->output, "Bootstrap: %s\n",
ssl->bootstrap_ca_cert ? "true" : "false");
} else {
ds_put_format(&ctx->output, "ssl for %s not found\n", owner);
}
}

static void
pre_cmd_del_ssl(struct ctl_context *ctx)
{
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssls);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_owner);
}

static void
cmd_del_ssl(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;

struct ovsrec_open_vswitch *ovs = vsctl_context_cast(ctx)->ovs;
struct ovsrec_ssl **ssls;
struct ovsrec_ssl *ssl = NULL;
size_t n = 0;
char *owner = ctx->argv[1];
check_ssl_owner(owner);

ssls = xmalloc(sizeof(*ovs->ssls) * (ovs->n_ssls));
for (size_t i = 0; i < ovs->n_ssls; i++) {
if (strcmp(ovs->ssls[i]->owner, owner) == 0) {
ssl = ovs->ssls[i];
} else {
ssls[n] = ovs->ssls[i];
n++;
}
}

if (ssl) {
ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
ovsrec_open_vswitch_verify_ssls(ovs);
ovsrec_ssl_delete(ssl);
ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
ovsrec_open_vswitch_set_ssls(ovs, ssls, n);
}
free(ssls);
ssls = NULL;
}

static void
pre_cmd_set_ssl(struct ctl_context *ctx)
{
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssls);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_owner);
}

static void
cmd_set_ssl(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
struct ovsrec_open_vswitch *ovs = vsctl_context_cast(ctx)->ovs;
struct ovsrec_ssl **ssls;
struct ovsrec_ssl *ssl = NULL;
bool bootstrap = shash_find(&ctx->options, "--bootstrap");
struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;

ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
size_t n = 0;
char *owner = ctx->argv[1];
check_ssl_owner(owner);

ssls = xmalloc(sizeof(*ovs->ssls) * (ovs->n_ssls + 1));
for (size_t i = 0; i < ovs->n_ssls; i++) {
if (strcmp(ovs->ssls[i]->owner, owner) == 0) {
ssl = ovs->ssls[i];
} else {
ssls[n] = ovs->ssls[i];
n++;
}
}

ovsrec_open_vswitch_verify_ssls(ovs);
if (ssl) {
ovsrec_ssl_delete(ssl);
}
ssl = ovsrec_ssl_insert(ctx->txn);

ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);

ovsrec_ssl_set_owner(ssl, owner);
ovsrec_ssl_set_private_key(ssl, ctx->argv[2]);
ovsrec_ssl_set_certificate(ssl, ctx->argv[3]);
ovsrec_ssl_set_ca_cert(ssl, ctx->argv[4]);
ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);

ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, ssl);

ssls[n] = ssl;
n++;
ovsrec_open_vswitch_set_ssls(ovs, ssls, n);
free(ssls);
ssls = NULL;
}

static void
Expand Down Expand Up @@ -3118,9 +3178,9 @@ static const struct ctl_command_syntax vsctl_commands[] = {
NULL, "--inactivity-probe=", RW},

/* SSL commands. */
{"get-ssl", 0, 0, "", pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
{"del-ssl", 0, 0, "", pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},
{"set-ssl", 3, 3, "PRIVATE-KEY CERTIFICATE CA-CERT", pre_cmd_set_ssl,
{"get-ssl", 1, 1, "{ovsdb | openflow}", pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
{"del-ssl", 1, 1, "{ovsdb | openflow}", pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},
{"set-ssl", 4, 4, "{ovsdb | openflow} PRIVATE-KEY CERTIFICATE CA-CERT", pre_cmd_set_ssl,
cmd_set_ssl, NULL, "--bootstrap", RW},

/* Auto Attach commands. */
Expand Down
9 changes: 8 additions & 1 deletion vswitchd/bridge.c
Expand Up @@ -3315,7 +3315,14 @@ bridge_run(void)
*
* We do this before bridge_reconfigure() because that function might
* initiate SSL connections and thus requires SSL to be configured. */
if (cfg && cfg->ssl) {
const struct ovsrec_ssl *ssl = NULL;
for (size_t i = 0; i < cfg->n_ssls; i++) {
if (strcmp(cfg->ssls[i]->owner, OPENFLOW_SSL_OWNER) == 0) {
ssl = cfg->ssls[i];
break;
}
}
if (ssl) {
const struct ovsrec_ssl *ssl = cfg->ssl;

stream_ssl_set_key_and_cert(ssl->private_key, ssl->certificate);
Expand Down
2 changes: 2 additions & 0 deletions vswitchd/bridge.h
Expand Up @@ -28,4 +28,6 @@ void bridge_wait(void);

void bridge_get_memory_usage(struct simap *usage);

#define OPENFLOW_SSL_OWNER "openflow"

#endif /* bridge.h */
10 changes: 6 additions & 4 deletions vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
"version": "8.3.0",
"cksum": "3781850481 26690",
"cksum": "3090718775 26738",
"tables": {
"Open_vSwitch": {
"columns": {
Expand All @@ -17,10 +17,10 @@
"type": {"key": {"type": "uuid",
"refTable": "Manager"},
"min": 0, "max": "unlimited"}},
"ssl": {
"ssls": {
"type": {"key": {"type": "uuid",
"refTable": "SSL"},
"min": 0, "max": 1}},
"min": 0, "max": 2}},
"other_config": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}},
Expand Down Expand Up @@ -692,6 +692,8 @@
"min": 0, "max": "unlimited"}}}},
"SSL": {
"columns": {
"owner": {
"type": "string"},
"private_key": {
"type": "string"},
"certificate": {
Expand All @@ -703,7 +705,7 @@
"external_ids": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
"maxRows": 1},
"maxRows": 2},
"AutoAttach": {
"columns": {
"system_name": {
Expand Down
5 changes: 4 additions & 1 deletion vswitchd/vswitch.xml
Expand Up @@ -63,7 +63,7 @@
Set of bridges managed by the daemon.
</column>

<column name="ssl">
<column name="ssls">
SSL used globally by the daemon.
</column>

Expand Down Expand Up @@ -6396,6 +6396,9 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \

<table name="SSL">
SSL configuration for an Open_vSwitch.
<column name="owner">
Name of the module that SSL configuration belongs to.
</column>

<column name="private_key">
Name of a PEM file containing the private key used as the switch's
Expand Down

0 comments on commit 4340678

Please sign in to comment.