Skip to content

Commit

Permalink
ovsdb-server: Announce bound listening ports as status:bound_port.
Browse files Browse the repository at this point in the history
The administrator can request that OVSDB bind any available TCP port, but
in that case there is no easy way to find out what port it has bound.  This
commit adds that information as the "bound_port" key in the "status"
column.

Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
blp committed Apr 18, 2013
1 parent 1e04fcc commit 798e135
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 21 deletions.
4 changes: 3 additions & 1 deletion lib/stream-provider.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2012 Nicira, Inc.
* Copyright (c) 2009, 2010, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -139,9 +139,11 @@ struct stream_class {
struct pstream {
const struct pstream_class *class;
char *name;
ovs_be16 bound_port;
};

void pstream_init(struct pstream *, const struct pstream_class *, const char *name);
void pstream_set_bound_port(struct pstream *, ovs_be16 bound_port);
static inline void pstream_assert_class(const struct pstream *pstream,
const struct pstream_class *class)
{
Expand Down
3 changes: 2 additions & 1 deletion lib/stream-ssl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -808,6 +808,7 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,

pssl = xmalloc(sizeof *pssl);
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
pstream_set_bound_port(&pssl->pstream, sin.sin_port);
pssl->fd = fd;
*pstreamp = &pssl->pstream;
return 0;
Expand Down
11 changes: 8 additions & 3 deletions lib/stream-tcp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -108,6 +108,7 @@ ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
{
struct sockaddr_in sin;
char bound_name[128];
int error;
int fd;

fd = inet_open_passive(SOCK_STREAM, suffix, -1, &sin, dscp);
Expand All @@ -117,8 +118,12 @@ ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,

sprintf(bound_name, "ptcp:%"PRIu16":"IP_FMT,
ntohs(sin.sin_port), IP_ARGS(sin.sin_addr.s_addr));
return new_fd_pstream(bound_name, fd, ptcp_accept, set_dscp, NULL,
pstreamp);
error = new_fd_pstream(bound_name, fd, ptcp_accept, set_dscp, NULL,
pstreamp);
if (!error) {
pstream_set_bound_port(*pstreamp, sin.sin_port);
}
return error;
}

static int
Expand Down
17 changes: 16 additions & 1 deletion lib/stream.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -621,6 +621,14 @@ pstream_set_dscp(struct pstream *pstream, uint8_t dscp)
}
return 0;
}

/* Returns the transport port on which 'pstream' is listening, or 0 if the
* concept doesn't apply. */
ovs_be16
pstream_get_bound_port(const struct pstream *pstream)
{
return pstream->bound_port;
}

/* Initializes 'stream' as a new stream named 'name', implemented via 'class'.
* The initial connection status, supplied as 'connect_status', is interpreted
Expand Down Expand Up @@ -681,9 +689,16 @@ void
pstream_init(struct pstream *pstream, const struct pstream_class *class,
const char *name)
{
memset(pstream, 0, sizeof *pstream);
pstream->class = class;
pstream->name = xstrdup(name);
}

void
pstream_set_bound_port(struct pstream *pstream, ovs_be16 port)
{
pstream->bound_port = port;
}

static int
count_fields(const char *s_)
Expand Down
4 changes: 3 additions & 1 deletion lib/stream.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2009, 2010, 2011, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -66,6 +66,8 @@ int pstream_accept(struct pstream *, struct stream **);
int pstream_accept_block(struct pstream *, struct stream **);
void pstream_wait(struct pstream *);
int pstream_set_dscp(struct pstream *, uint8_t dscp);

ovs_be16 pstream_get_bound_port(const struct pstream *);

/* Convenience functions. */

Expand Down
4 changes: 4 additions & 0 deletions ovsdb/jsonrpc-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,10 @@ ovsdb_jsonrpc_session_get_status(const struct ovsdb_jsonrpc_remote *remote,
struct reconnect_stats rstats;
struct ds locks_held, locks_waiting, locks_lost;

status->bound_port = (remote->listener
? pstream_get_bound_port(remote->listener)
: htons(0));

if (list_is_empty(&remote->sessions)) {
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion ovsdb/jsonrpc-server.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
#define OVSDB_JSONRPC_SERVER_H 1

#include <stdbool.h>
#include "openvswitch/types.h"

struct ovsdb;
struct shash;
Expand Down Expand Up @@ -50,6 +51,7 @@ struct ovsdb_jsonrpc_remote_status {
char *locks_waiting;
char *locks_lost;
int n_connections;
ovs_be16 bound_port;
};
bool ovsdb_jsonrpc_server_get_remote_status(
const struct ovsdb_jsonrpc_server *, const char *target,
Expand Down
7 changes: 6 additions & 1 deletion ovsdb/ovsdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <signal.h>
#include <unistd.h>

Expand Down Expand Up @@ -683,7 +684,7 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn,
struct ovsdb_jsonrpc_remote_status status;
struct ovsdb_row *rw_row;
const char *target;
char *keys[8], *values[8];
char *keys[9], *values[9];
size_t n = 0;

/* Get the "target" (protocol/host/port) spec. */
Expand Down Expand Up @@ -730,6 +731,10 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn,
keys[n] = xstrdup("n_connections");
values[n++] = xasprintf("%d", status.n_connections);
}
if (status.bound_port != htons(0)) {
keys[n] = xstrdup("bound_port");
values[n++] = xasprintf("%"PRIu16, ntohs(status.bound_port));
}
write_string_string_column(rw_row, "status", keys, values, n);

ovsdb_jsonrpc_server_free_remote_status(&status);
Expand Down
2 changes: 1 addition & 1 deletion tests/ofproto-dpif.at
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,7 @@ dnl Test that sFlow samples packets correctly.
AT_SETUP([ofproto-dpif - sFlow packet sampling])
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])

ON_EXIT([kill `cat test-sflow.pid`])
AT_CHECK([test-sflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > sflow.log], [0], [], [ignore])
AT_CAPTURE_FILE([sflow.log])
SFLOW_PORT=`parse_listening_port < test-sflow.log`
Expand All @@ -1224,7 +1225,6 @@ ovs-vsctl \
set Bridge br0 sflow=@sf -- \
--id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" \
header=128 sampling=1 polling=1
ON_EXIT([kill `cat test-sflow.pid`])

dnl open with ARP packets to seed the bridge-learning. The output
dnl ifIndex numbers should be reported predictably after that.
Expand Down
10 changes: 5 additions & 5 deletions tests/ofproto-macros.at
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ s/ hard_age=[0-9]*,//

# parse_listening_port [SERVER]
#
# Parses the TCP or SSL port on which a server is listening from the log,
# given that the server was told to listen on a kernel-chosen port,
# file provided on stdin, and prints the port number on stdout.
# Parses the TCP or SSL port on which a server is listening from the
# log, given that the server was told to listen on a kernel-chosen
# port, file provided on stdin, and prints the port number on stdout.
# You should specify the listening remote as ptcp:0:127.0.0.1 or
# pssl:0:127.0.0.1.
#
# Here's an example of how to use this with ovsdb-server:
#
# OVS_LOGDIR=`pwd`; export OVS_LOGDIR
# ovsdb-server --log-file --remote=ptcp:0:127.0.0.1 ...
# TCP_PORT=`parse_listening_port < ovsdb-server.log`
#
# (Also works with pssl: in place of ptcp:.)
parse_listening_port () {
sed -n 's/.*0:127\.0\.0\.1: listening on port \([0-9]*\)$/\1/p'
}]
Expand Down
23 changes: 17 additions & 6 deletions vswitchd/vswitch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2836,9 +2836,11 @@
<dd>
<p>
Listens for SSL connections on the specified TCP <var>port</var>
(default: 6632). If <var>ip</var>, which must be expressed as an
IP address (not a DNS name), is specified, then connections are
restricted to the specified local IP address.
(default: 6632). Specify 0 for <var>port</var> to have the
kernel automatically choose an available port. If <var>ip</var>,
which must be expressed as an IP address (not a DNS name), is
specified, then connections are restricted to the specified local
IP address.
</p>
<p>
The <ref table="Open_vSwitch" column="ssl"/> column in the <ref
Expand All @@ -2853,9 +2855,10 @@
<dt><code>ptcp:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
<dd>
Listens for connections on the specified TCP <var>port</var>
(default: 6632). If <var>ip</var>, which must be expressed as an
IP address (not a DNS name), is specified, then connections are
restricted to the specified local IP address.
(default: 6632). Specify 0 for <var>port</var> to have the kernel
automatically choose an available port. If <var>ip</var>, which
must be expressed as an IP address (not a DNS name), is specified,
then connections are restricted to the specified local IP address.
</dd>
</dl>
<p>When multiple managers are configured, the <ref column="target"/>
Expand Down Expand Up @@ -2999,6 +3002,14 @@
chosen connection.
</p>
</column>

<column name="status" key="bound_port" type='{"type": "integer"}'>
When <ref column="target"/> is <code>ptcp:</code> or
<code>pssl:</code>, this is the TCP port on which the OVSDB server is
listening. (This is is particularly useful when <ref
column="target"/> specifies a port of 0, allowing the kernel to
choose any available port.)
</column>
</group>

<group title="Connection Parameters">
Expand Down

0 comments on commit 798e135

Please sign in to comment.