Skip to content

Commit

Permalink
ovn: l3ha, CLI for logical router port gateway chassis
Browse files Browse the repository at this point in the history
This change adds commands to set, get and delete gateway chassis
for logical router port.

Signed-off-by: Venkata Anil Kommaddi <[email protected]>
Signed-off-by: Russell Bryant <[email protected]>
  • Loading branch information
venkataanil authored and russellb committed Jul 27, 2017
1 parent dfaf79d commit 36f232b
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 0 deletions.
23 changes: 23 additions & 0 deletions ovn/utilities/ovn-nbctl.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,29 @@
Prints the administrative state of <var>port</var>, either
<code>enabled</code> or <code>disabled</code>.
</dd>

<dt><code>lrp-set-gateway-chassis</code> <var>port</var>
<var>chassis</var> [<var>priority</var>]</dt>
<dd>
Set gateway chassis for <var>port</var>. <var>chassis</var>
is the name of the chassis. This creates a gateway chassis entry
in Gateway_Chassis table. It won't check if chassis really exists
in OVN_Southbound database. Priority will be set to 0
if <var>priority</var> is not provided by user. <var>priority</var>
must be between <code>0</code> and <code>32767</code>, inclusive.
</dd>
<dt><code>lrp-del-gateway-chassis</code> <var>port</var>
<var>chassis</var></dt>
<dd>
Deletes gateway chassis from <var>port</var>. It is an error if
gateway chassis with <var>chassis</var> for <var>port</var> does
not exist.
</dd>
<dt><code>lrp-get-gateway-chassis</code> <var>port</var></dt>
<dd>
Lists all the gateway chassis with priority within <var>port</var> on
standard output, one per line, ordered based on priority.
</dd>
</dl>

<h1>Logical Router Static Route Commands</h1>
Expand Down
186 changes: 186 additions & 0 deletions ovn/utilities/ovn-nbctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,13 @@ Logical router commands:\n\
Logical router port commands:\n\
lrp-add ROUTER PORT MAC NETWORK... [peer=PEER]\n\
add logical port PORT on ROUTER\n\
lrp-set-gateway-chassis PORT CHASSIS [PRIORITY]\n\
set gateway chassis for port PORT\n\
lrp-del-gateway-chassis PORT CHASSIS\n\
delete gateway chassis from port PORT\n\
lrp-get-gateway-chassis PORT\n\
print the names of all gateway chassis on PORT\n\
with PRIORITY\n\
lrp-del PORT delete PORT from its attached router\n\
lrp-list ROUTER print the names of all ports on ROUTER\n\
lrp-set-enabled PORT STATE\n\
Expand Down Expand Up @@ -2528,6 +2535,178 @@ lr_get_name(const struct nbrec_logical_router *lr, char uuid_s[UUID_LEN + 1],
return uuid_s;
}

static const struct nbrec_gateway_chassis *
gc_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist)
{
const struct nbrec_gateway_chassis *gc = NULL;

struct uuid gc_uuid;
bool is_uuid = uuid_from_string(&gc_uuid, id);
if (is_uuid) {
gc = nbrec_gateway_chassis_get_for_uuid(ctx->idl, &gc_uuid);
}

if (!gc) {
NBREC_GATEWAY_CHASSIS_FOR_EACH (gc, ctx->idl) {
if (!strcmp(gc->name, id)) {
break;
}
}
}

if (!gc && must_exist) {
ctl_fatal("%s: gateway chassis %s not found", id,
is_uuid ? "UUID" : "name");
}

return gc;
}

static void
nbctl_lrp_set_gateway_chassis(struct ctl_context *ctx)
{
char *gc_name;
int64_t priority = 0;
const char *lrp_name = ctx->argv[1];
const struct nbrec_logical_router_port *lrp;
lrp = lrp_by_name_or_uuid(ctx, lrp_name, true);
if (!lrp) {
ctl_fatal("router port %s is required", lrp_name);
return;
}

const char *chassis_name = ctx->argv[2];
if (ctx->argv[3]) {
priority = parse_priority(ctx->argv[3]);
}

gc_name = xasprintf("%s-%s", lrp_name, chassis_name);
const struct nbrec_gateway_chassis *existing_gc;
existing_gc = gc_by_name_or_uuid(ctx, gc_name, false);
if (existing_gc) {
nbrec_gateway_chassis_set_priority(existing_gc, priority);
free(gc_name);
return;
}

/* Create the logical gateway chassis. */
struct nbrec_gateway_chassis *gc
= nbrec_gateway_chassis_insert(ctx->txn);
nbrec_gateway_chassis_set_name(gc, gc_name);
nbrec_gateway_chassis_set_chassis_name(gc, chassis_name);
nbrec_gateway_chassis_set_priority(gc, priority);

/* Insert the logical gateway chassis into the logical router port. */
nbrec_logical_router_port_verify_gateway_chassis(lrp);
struct nbrec_gateway_chassis **new_gc = xmalloc(
sizeof *new_gc * (lrp->n_gateway_chassis + 1));
nullable_memcpy(new_gc, lrp->gateway_chassis,
sizeof *new_gc * lrp->n_gateway_chassis);
new_gc[lrp->n_gateway_chassis] = gc;
nbrec_logical_router_port_set_gateway_chassis(
lrp, new_gc, lrp->n_gateway_chassis + 1);
free(new_gc);
free(gc_name);
}

/* Removes logical router port 'lrp->gateway_chassis[idx]'. */
static void
remove_gc(const struct nbrec_logical_router_port *lrp, size_t idx)
{
const struct nbrec_gateway_chassis *gc = lrp->gateway_chassis[idx];

if (lrp->n_gateway_chassis == 1) {
nbrec_logical_router_port_set_gateway_chassis(lrp, NULL, 0);
} else {
/* First remove 'gc' from the array of gateway_chassis. This is what
* will actually cause the gateway chassis to be deleted when the
* transaction is sent to the database server (due to garbage
* collection). */
struct nbrec_gateway_chassis **new_gc
= xmemdup(lrp->gateway_chassis,
sizeof *new_gc * lrp->n_gateway_chassis);
new_gc[idx] = new_gc[lrp->n_gateway_chassis - 1];
nbrec_logical_router_port_verify_gateway_chassis(lrp);
nbrec_logical_router_port_set_gateway_chassis(
lrp, new_gc, lrp->n_gateway_chassis - 1);
free(new_gc);
}

/* Delete 'gc' from the IDL. This won't have a real effect on
* the database server (the IDL will suppress it in fact) but it
* means that it won't show up when we iterate with
* NBREC_GATEWAY_CHASSIS_FOR_EACH later. */
nbrec_gateway_chassis_delete(gc);
}

static void
nbctl_lrp_del_gateway_chassis(struct ctl_context *ctx)
{
const struct nbrec_logical_router_port *lrp;
lrp = lrp_by_name_or_uuid(ctx, ctx->argv[1], true);
if (!lrp) {
return;
}
/* Find the lrp that contains 'gc', then delete it. */
const char *chassis_name = ctx->argv[2];
for (size_t i = 0; i < lrp->n_gateway_chassis; i++) {
if (!strncmp(lrp->gateway_chassis[i]->chassis_name,
chassis_name,
strlen(lrp->gateway_chassis[i]->chassis_name))) {
remove_gc(lrp, i);
return;
}
}

/* Can't happen because of the database schema. */
ctl_fatal("chassis %s is not added to logical port %s",
chassis_name, ctx->argv[1]);
}

/* gateway_chassis ordering
* */
static int
compare_chassis_prio_(const void *gc1_, const void *gc2_)
{
const struct nbrec_gateway_chassis *const *gc1p = gc1_;
const struct nbrec_gateway_chassis *const *gc2p = gc2_;
const struct nbrec_gateway_chassis *gc1 = *gc1p;
const struct nbrec_gateway_chassis *gc2 = *gc2p;

int prio_diff = gc2->priority - gc1->priority;
if (!prio_diff) {
return strcmp(gc2->name, gc1->name);
}
return prio_diff;
}

/* Print a list of gateway chassis. */
static void
nbctl_lrp_get_gateway_chassis(struct ctl_context *ctx)
{
const char *id = ctx->argv[1];
const struct nbrec_logical_router_port *lrp;
const struct nbrec_gateway_chassis **gcs;
size_t i;

lrp = lrp_by_name_or_uuid(ctx, id, true);

gcs = xmalloc(sizeof *gcs * lrp->n_gateway_chassis);
for (i = 0; i < lrp->n_gateway_chassis; i++) {
gcs[i] = lrp->gateway_chassis[i];
}

qsort(gcs, lrp->n_gateway_chassis, sizeof *gcs, compare_chassis_prio_);

for (i = 0; i < lrp->n_gateway_chassis; i++) {
const struct nbrec_gateway_chassis *gc = gcs[i];
ds_put_format(&ctx->output, "%s %5"PRId64"\n",
gc->name, gc->priority);
}

free(gcs);
}

static void
nbctl_lrp_add(struct ctl_context *ctx)
{
Expand Down Expand Up @@ -3413,6 +3592,13 @@ static const struct ctl_command_syntax nbctl_commands[] = {
{ "lrp-add", 4, INT_MAX,
"ROUTER PORT MAC NETWORK... [COLUMN[:KEY]=VALUE]...",
NULL, nbctl_lrp_add, NULL, "--may-exist", RW },
{ "lrp-set-gateway-chassis", 2, 3,
"PORT CHASSIS [PRIORITY]",
NULL, nbctl_lrp_set_gateway_chassis, NULL, "--may-exist", RW },
{ "lrp-del-gateway-chassis", 2, 2, "PORT CHASSIS", NULL,
nbctl_lrp_del_gateway_chassis, NULL, "", RW },
{ "lrp-get-gateway-chassis", 1, 1, "PORT", NULL,
nbctl_lrp_get_gateway_chassis, NULL, "", RO },
{ "lrp-del", 1, 1, "PORT", NULL, nbctl_lrp_del, NULL, "--if-exists", RW },
{ "lrp-list", 1, 1, "ROUTER", NULL, nbctl_lrp_list, NULL, "", RO },
{ "lrp-set-enabled", 2, 2, "PORT STATE", NULL, nbctl_lrp_set_enabled,
Expand Down
55 changes: 55 additions & 0 deletions tests/ovn-nbctl.at
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,61 @@ AT_CLEANUP

dnl ---------------------------------------------------------------------

AT_SETUP([ovn-nbctl - logical router port gateway chassis])
OVN_NBCTL_TEST_START
AT_CHECK([ovn-nbctl lr-add lr0])
AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [])

AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lp0 chassis1], [1], [],
[ovn-nbctl: lp0: port name not found
])

AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lp0], [1], [],
[ovn-nbctl: lp0: port name not found
])

AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lp0 chassis1], [1], [],
[ovn-nbctl: lp0: port name not found
])

AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis1], [1], [],
[ovn-nbctl: chassis chassis1 is not added to logical port lrp0
])
AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1])

AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
lrp0-chassis1 0
])
AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1 10])

AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
lrp0-chassis1 10
])
AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1 20])

AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
lrp0-chassis1 20
])
AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis2 5])
AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
lrp0-chassis1 20
lrp0-chassis2 5
])

AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis1])
AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
lrp0-chassis2 5
])

AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis2])
AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0])

OVN_NBCTL_TEST_STOP
AT_CLEANUP

dnl ---------------------------------------------------------------------

AT_SETUP([ovn-nbctl - logical router port enable and disable])
OVN_NBCTL_TEST_START

Expand Down

0 comments on commit 36f232b

Please sign in to comment.