From: Ben Pfaff Date: Thu, 18 Apr 2013 23:37:05 +0000 (-0700) Subject: ovsdb-server: Announce bound listening ports as status:bound_port. X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=798e1352d09bc48d1eecb6ecf1b2c21d9b1ba2a5;p=sliver-openvswitch.git ovsdb-server: Announce bound listening ports as status:bound_port. 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 --- diff --git a/lib/stream-provider.h b/lib/stream-provider.h index 1db373549..43c63e81b 100644 --- a/lib/stream-provider.h +++ b/lib/stream-provider.h @@ -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. @@ -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) { diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index 23c5591fc..ddf65a325 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -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. @@ -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; diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c index 0384c42f9..1767fe44e 100644 --- a/lib/stream-tcp.c +++ b/lib/stream-tcp.c @@ -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. @@ -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); @@ -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 diff --git a/lib/stream.c b/lib/stream.c index 0c6a8c13f..da089ae4b 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -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. @@ -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 @@ -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_) diff --git a/lib/stream.h b/lib/stream.h index d2f2ebb75..aa3fa9d48 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -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. @@ -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. */ diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index febc351dd..9f99d6401 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -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; } diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h index bf2a2fcae..f2395fc98 100644 --- a/ovsdb/jsonrpc-server.h +++ b/ovsdb/jsonrpc-server.h @@ -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. @@ -17,6 +17,7 @@ #define OVSDB_JSONRPC_SERVER_H 1 #include +#include "openvswitch/types.h" struct ovsdb; struct shash; @@ -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, diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 61095e29b..a8daf1f59 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -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. */ @@ -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); diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 0de941ea2..fef5f9593 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -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` @@ -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. diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at index cad00804a..73c6c282b 100644 --- a/tests/ofproto-macros.at +++ b/tests/ofproto-macros.at @@ -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' }] diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 2af04bd1d..21bcbc2e5 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -2836,9 +2836,11 @@

Listens for SSL connections on the specified TCP port - (default: 6632). If ip, 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 port to have the + kernel automatically choose an available port. If ip, + which must be expressed as an IP address (not a DNS name), is + specified, then connections are restricted to the specified local + IP address.

The column in the ptcp:[port][:ip]

Listens for connections on the specified TCP port - (default: 6632). If ip, 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 port to have the kernel + automatically choose an available port. If ip, which + must be expressed as an IP address (not a DNS name), is specified, + then connections are restricted to the specified local IP address.

When multiple managers are configured, the @@ -2999,6 +3002,14 @@ chosen connection.

+ + + When is ptcp: or + pssl:, this is the TCP port on which the OVSDB server is + listening. (This is is particularly useful when specifies a port of 0, allowing the kernel to + choose any available port.) +