From: Ben Pfaff Date: Wed, 30 Jul 2008 22:45:21 +0000 (-0700) Subject: vconn: Implement Unix domain socket vconn. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bab6bdbe58cafa206e8831a49f65046dc0c56623;p=openvswitch vconn: Implement Unix domain socket vconn. These are useful for local management connections because, unlike TCP sockets, they are subject to regular file system permissions. --- diff --git a/controller/controller.8.in b/controller/controller.8.in index 25f9c322..a8299519 100644 --- a/controller/controller.8.in +++ b/controller/controller.8.in @@ -28,6 +28,11 @@ this form is used. Listens for TCP connections from remote OpenFlow switches on \fIport\fR (default: 975). +.TP +\fBpunix:\fIfile\fR +Listens for connections from OpenFlow switches on the Unix domain +server socket named \fIfile\fR. + .TP \fBnl:\fIdp_idx\fR The local Netlink datapath numbered \fIdp_idx\fR, as configured with @@ -46,6 +51,10 @@ The specified SSL \fIport\fR (default: 976) on the given remote The specified TCP \fIport\fR (default: 975) on the given remote \fIhost\fR. +.TP +\fBunix:\fIfile\fR +The Unix domain server socket named \fIfile\fR. + .SH OPTIONS .TP \fB-p\fR, \fB--private-key=\fIprivkey.pem\fR diff --git a/include/vconn.h b/include/vconn.h index 8dc35f0c..4b0eaa7e 100644 --- a/include/vconn.h +++ b/include/vconn.h @@ -173,6 +173,8 @@ struct vconn_class { extern struct vconn_class tcp_vconn_class; extern struct vconn_class ptcp_vconn_class; +extern struct vconn_class unix_vconn_class; +extern struct vconn_class punix_vconn_class; #ifdef HAVE_OPENSSL extern struct vconn_class ssl_vconn_class; extern struct vconn_class pssl_vconn_class; diff --git a/include/vlog.h b/include/vlog.h index a25c5281..f2641b09 100644 --- a/include/vlog.h +++ b/include/vlog.h @@ -86,6 +86,7 @@ enum vlog_facility vlog_get_facility_val(const char *name); VLOG_MODULE(vconn_tcp) \ VLOG_MODULE(vconn_ssl) \ VLOG_MODULE(vconn_stream) \ + VLOG_MODULE(vconn_unix) \ VLOG_MODULE(vconn) \ VLOG_MODULE(vlog) \ diff --git a/lib/Makefile.am b/lib/Makefile.am index 6c13fc58..3d2a4ef7 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -26,6 +26,7 @@ libopenflow_a_SOURCES = \ socket-util.c \ util.c \ vconn-tcp.c \ + vconn-unix.c \ vconn-stream.c \ vconn.c \ vlog-socket.c \ diff --git a/lib/vconn-unix.c b/lib/vconn-unix.c new file mode 100644 index 00000000..f8b6cbc2 --- /dev/null +++ b/lib/vconn-unix.c @@ -0,0 +1,128 @@ +/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford + * Junior University + * + * We are making the OpenFlow specification and associated documentation + * (Software) available for public use and benefit with the expectation + * that others will use, modify and enhance the Software and contribute + * those enhancements back to the community. However, since we would + * like to make the Software available for broadest use, with as few + * restrictions as possible permission is hereby granted, free of + * charge, to any person obtaining a copy of this Software to deal in + * the Software under the copyrights without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The name and trademarks of copyright holder(s) may NOT be used in + * advertising or publicity pertaining to the Software or any + * derivatives without specific, written prior permission. + */ + +#include +#include "vconn.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "buffer.h" +#include "socket-util.h" +#include "util.h" +#include "openflow.h" +#include "ofp-print.h" +#include "packets.h" +#include "poll-loop.h" +#include "vconn-stream.h" + +#include "vlog.h" +#define THIS_MODULE VLM_vconn_unix + +/* Active UNIX socket. */ + +/* Number of unix sockets created so far, to ensure binding path uniqueness. */ +static int n_unix_sockets; + +static int +unix_open(const char *name, char *suffix, struct vconn **vconnp) +{ + const char *connect_path = suffix; + char bind_path[128]; + int fd; + + sprintf(bind_path, "/tmp/vconn-unix.%ld.%d", + (long int) getpid(), n_unix_sockets++); + fd = make_unix_socket(SOCK_STREAM, true, false, bind_path, connect_path); + if (fd < 0) { + VLOG_ERR("%s: connection to %s failed: %s", + bind_path, connect_path, strerror(-fd)); + return -fd; + } + + return new_stream_vconn(name, fd, check_connection_completion(fd), + 0, vconnp); +} + +struct vconn_class unix_vconn_class = { + .name = "unix", + .open = unix_open, +}; + +/* Passive UNIX socket. */ + +static int punix_accept(int fd, const struct sockaddr *sa, size_t sa_len, + struct vconn **vconnp); + +static int +punix_open(const char *name, char *suffix, struct vconn **vconnp) +{ + int fd; + + fd = make_unix_socket(SOCK_STREAM, true, true, suffix, NULL); + if (fd < 0) { + VLOG_ERR("%s: binding failed: %s", suffix, strerror(errno)); + return errno; + } + + return new_pstream_vconn("punix", fd, punix_accept, vconnp); +} + +static int +punix_accept(int fd, const struct sockaddr *sa, size_t sa_len, + struct vconn **vconnp) +{ + const struct sockaddr_un *sun = (const struct sockaddr_un *) sa; + char name[128]; + + if (sa_len >= offsetof(struct sockaddr_un, sun_path)) { + snprintf(name, sizeof name, "unix:%.*s", + (int) (sa_len - offsetof(struct sockaddr_un, sun_path)), + sun->sun_path); + } else { + strcpy(name, "unix"); + } + return new_stream_vconn(name, fd, 0, 0, vconnp); +} + +struct vconn_class punix_vconn_class = { + .name = "punix", + .open = punix_open, +}; + diff --git a/lib/vconn.c b/lib/vconn.c index 8638efbe..7af59f38 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -61,6 +61,8 @@ static struct vconn_class *vconn_classes[] = { &ssl_vconn_class, &pssl_vconn_class, #endif + &unix_vconn_class, + &punix_vconn_class, }; /* Check the validity of the vconn class structures. */ @@ -110,6 +112,7 @@ vconn_usage(bool active, bool passive) printf(" ssl:HOST[:PORT] " "SSL PORT (default: %d) on remote HOST\n", OFP_SSL_PORT); #endif + printf(" unix:FILE Unix domain socket named FILE\n"); } if (passive) { @@ -122,6 +125,8 @@ vconn_usage(bool active, bool passive) "listen for SSL on PORT (default: %d)\n", OFP_SSL_PORT); #endif + printf(" punix:FILE " + "listen on Unix domain socket FILE\n"); } #ifdef HAVE_OPENSSL diff --git a/secchan/secchan.8.in b/secchan/secchan.8.in index 03c516cf..12f390b0 100644 --- a/secchan/secchan.8.in +++ b/secchan/secchan.8.in @@ -32,6 +32,10 @@ The specified SSL \fIport\fR (default: 976) on the given remote The specified TCP \fIport\fR (default: 975) on the given remote \fIhost\fR. +.TP +\fBunix:\fIfile\fR +The Unix domain server socket named \fIfile\fR. + If \fIcontroller\fR is omitted, \fBsecchan\fR attempts to discover the location of the controller automatically (see below). @@ -292,6 +296,10 @@ are mandatory when this form is used. Listens for TCP connections on \fIport\fR (default: 975). .RE +.TP +\fBpunix:\fIfile\fR +Listens for connections on Unix domain server socket named \fIfile\fR. + .TP \fB-p\fR, \fB--private-key=\fIprivkey.pem\fR Specifies a PEM file containing the private key used as the switch's diff --git a/switch/switch.8.in b/switch/switch.8.in index a4fcb0e7..1bd0607a 100644 --- a/switch/switch.8.in +++ b/switch/switch.8.in @@ -42,6 +42,10 @@ The specified SSL \fIport\fR (default: 976) on the given remote The specified TCP \fIport\fR (default: 975) on the given remote \fIhost\fR. +.TP +\fBunix:\fIfile\fR +The Unix domain server socket named \fIfile\fR. + .SH OPTIONS .TP \fB-i\fR, \fB--interfaces=\fR\fInetdev\fR[\fB,\fInetdev\fR]... diff --git a/utilities/dpctl.8 b/utilities/dpctl.8 index 043ff143..fc4cd311 100644 --- a/utilities/dpctl.8 +++ b/utilities/dpctl.8 @@ -37,6 +37,10 @@ The specified SSL \fIport\fR (default: 976) on the given remote The specified TCP \fIport\fR (default: 975) on the given remote \fIhost\fR. +.TP +\fBunix:\fIfile\fR +The Unix domain server socket named \fIfile\fR. + .SH COMMANDS With the \fBdpctl\fR program, datapaths running in the kernel can be