[ovs-dev] [PATCH] Support IPv6 link-local address scopes on Linux.
Darrell Ball
dball at vmware.com
Tue Jul 11 23:30:29 UTC 2017
This looks correct to me and a reasonable subset of support of scoping, although I did not test it.
I noticed there was some unrelated cleanup w.r.t. parse_sockaddr_components(), but those
changes are minor.
Acked-by: Darrell Ball <dlu998 at gmail.com>
On 7/5/17, 5:20 PM, "ovs-dev-bounces at openvswitch.org on behalf of Ben Pfaff" <ovs-dev-bounces at openvswitch.org on behalf of blp at ovn.org> wrote:
I hadn't even heard of this feature before, but it seems to be at least
semi-standard to support Linux link-local address scopes via a % suffix,
e.g. fe80::1234%eth0 for a link-local address scoped to eth0. This commit
adds support.
I'd appreciate feedback from folks who understand this feature better than
me.
Reported-by: Ali Volkan Atli <Volkan.Atli at argela.com.tr>
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
NEWS | 2 ++
configure.ac | 3 +++
lib/socket-util.c | 31 ++++++++++++++++++++++---------
lib/vconn-active.man | 7 +++++--
lib/vconn-passive.man | 10 ++++++----
ovsdb/remote-active.man | 20 +++++++++-----------
ovsdb/remote-passive.man | 29 +++++++++++------------------
7 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/NEWS b/NEWS
index 0f2604ff5c51..c8c14481a1db 100644
--- a/NEWS
+++ b/NEWS
@@ -66,6 +66,8 @@ Post-v2.7.0
- Add experimental support for hardware offloading
* HW offloading is disabled by default.
* HW offloading is done through the TC interface.
+ - IPv6 link local addresses are now supported on Linux. Use % to designate
+ the scope device.
v2.7.0 - 21 Feb 2017
---------------------
diff --git a/configure.ac b/configure.ac
index 6404b5fc1222..9f78184f52a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,6 +106,9 @@ AC_CHECK_DECLS([sys_siglist], [], [], [[#include <signal.h>]])
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec],
[], [], [[#include <sys/stat.h>]])
AC_CHECK_MEMBERS([struct ifreq.ifr_flagshigh], [], [], [[#include <net/if.h>]])
+AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id], [], [],
+ [[#include <sys/socket.h>
+#include <netinet/in.h>]])
AC_CHECK_FUNCS([mlockall strnlen getloadavg statvfs getmntent_r])
AC_CHECK_HEADERS([mntent.h sys/statvfs.h linux/types.h linux/if_ether.h stdatomic.h])
AC_CHECK_HEADERS([net/if_mib.h], [], [], [[#include <sys/types.h>
diff --git a/lib/socket-util.c b/lib/socket-util.c
index 2c0f1e62bd99..fbed172bdefb 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -365,7 +365,7 @@ parse_bracketed_token(char **pp)
static bool
parse_sockaddr_components(struct sockaddr_storage *ss,
- const char *host_s,
+ char *host_s,
const char *port_s, uint16_t default_port,
const char *s)
{
@@ -382,20 +382,34 @@ parse_sockaddr_components(struct sockaddr_storage *ss,
}
memset(ss, 0, sizeof *ss);
- if (strchr(host_s, ':')) {
+ if (host_s && strchr(host_s, ':')) {
struct sockaddr_in6 *sin6
= ALIGNED_CAST(struct sockaddr_in6 *, ss);
+ char *addr = strsep(&host_s, "%");
+
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
- if (!ipv6_parse(host_s, &sin6->sin6_addr)) {
- VLOG_ERR("%s: bad IPv6 address \"%s\"", s, host_s);
+ if (!addr || !*addr || !ipv6_parse(addr, &sin6->sin6_addr)) {
+ VLOG_ERR("%s: bad IPv6 address \"%s\"", s, addr ? addr : "");
goto exit;
}
+
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
+ char *scope = strsep(&host_s, "%");
+ if (scope && *scope) {
+ sin6->sin6_scope_id = if_nametoindex(scope);
+ if (!sin6->sin6_scope_id) {
+ VLOG_ERR("%s: bad IPv6 scope \"%s\" (%s)",
+ s, scope, ovs_strerror(errno));
+ goto exit;
+ }
+ }
+#endif
} else {
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
- if (!ip_parse(host_s, &sin->sin_addr.s_addr)) {
+ if (host_s && !ip_parse(host_s, &sin->sin_addr.s_addr)) {
VLOG_ERR("%s: bad IPv4 address \"%s\"", s, host_s);
goto exit;
}
@@ -421,7 +435,7 @@ inet_parse_active(const char *target_, uint16_t default_port,
{
char *target = xstrdup(target_);
const char *port;
- const char *host;
+ char *host;
char *p;
bool ok;
@@ -548,7 +562,7 @@ inet_parse_passive(const char *target_, int default_port,
{
char *target = xstrdup(target_);
const char *port;
- const char *host;
+ char *host;
char *p;
bool ok;
@@ -559,8 +573,7 @@ inet_parse_passive(const char *target_, int default_port,
VLOG_ERR("%s: port must be specified", target_);
ok = false;
} else {
- ok = parse_sockaddr_components(ss, host ? host : "0.0.0.0",
- port, default_port, target_);
+ ok = parse_sockaddr_components(ss, host, port, default_port, target_);
}
if (!ok) {
memset(ss, 0, sizeof *ss);
diff --git a/lib/vconn-active.man b/lib/vconn-active.man
index 3e789cc88e16..395879c8a58b 100644
--- a/lib/vconn-active.man
+++ b/lib/vconn-active.man
@@ -3,8 +3,11 @@
The specified \fIport\fR on the host at the given \fIip\fR, which must
be expressed as an IP address (not a DNS name) in IPv4 or IPv6 address
format. Wrap IPv6 addresses in square brackets,
-e.g. \fBtcp:[::1]:6653\fR. For \fBssl\fR, the \fB\-\-private\-key\fR,
-\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR options are mandatory.
+e.g. \fBtcp:[::1]:6653\fR. On Linux, use \fB%\fIdevice\fR to
+designate a scope for IPv6 link-level addresses,
+e.g. \fBtcp:[fe80::1234%eth0]:6653\fR. For \fBssl\fR, the
+\fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
+options are mandatory.
.IP
If \fIport\fR is not specified, it defaults to 6653.
.TP
diff --git a/lib/vconn-passive.man b/lib/vconn-passive.man
index 9d9050b020ff..1ffa183972b8 100644
--- a/lib/vconn-passive.man
+++ b/lib/vconn-passive.man
@@ -1,10 +1,12 @@
.IP "\fBpssl:\fR[\fIport\fR][\fB:\fIip\fR]"
.IQ "\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]"
Listens for OpenFlow connections on \fIport\fR. The default
-\fIport\fR is 6653. By default, connections
-are allowed from any IPv4 address. Specify \fIip\fR as an IPv4
-address or a bracketed IPv6 address (e.g. \fBptcp:6653:[::1]\fR). DNS
-names may not be used. For \fBpssl\fR, the
+\fIport\fR is 6653. By default, connections are allowed from any IPv4
+address. Specify \fIip\fR as an IPv4 address or a bracketed IPv6
+address (e.g. \fBptcp:6653:[::1]\fR). On Linux, use \fB%\fIdevice\fR
+to designate a scope for IPv6 link-level addresses,
+e.g. \fBptcp:6653:[fe80::1234%eth0]\fR. DNS names may
+not be used. For \fBpssl\fR, the
\fB\-\-private\-key\fR,\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
options are mandatory.
.IP
diff --git a/ovsdb/remote-active.man b/ovsdb/remote-active.man
index 83d64652ddb9..bf5b323dd55e 100644
--- a/ovsdb/remote-active.man
+++ b/ovsdb/remote-active.man
@@ -1,15 +1,13 @@
.IP "\fBssl:\fIip\fB:\fIport\fR"
-The specified SSL \fIport\fR on the host at the given \fIip\fR, which
-must be expressed as an IP address (not a DNS name) in IPv4 or IPv6 address
-format. If \fIip\fR is an IPv6 address, then wrap \fIip\fR with square
-brackets, e.g.: \fBssl:[::1]:6640\fR.
-The \fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
-options are mandatory when this form is used.
-.
-.IP "\fBtcp:\fIip\fB:\fIport\fR"
-Connect to the given TCP \fIport\fR on \fIip\fR, where \fIip\fR can be IPv4
-or IPv6 address. If \fIip\fR is an IPv6 address, then wrap \fIip\fR with
-square brackets, e.g.: \fBtcp:[::1]:6640\fR.
+.IQ "\fBtcp:\fIip\fB:\fIport\fR"
+The given SSL or plain TCP \fIport\fR on the host at the given
+\fIip\fR, which must be expressed as an IP address (not a DNS name) in
+IPv4 or IPv6 address format. If \fIip\fR is an IPv6 address, then
+wrap \fIip\fR with square brackets, e.g.: \fBssl:[::1]:6640\fR. On
+Linux, use \fB%\fIdevice\fR to designate a scope for IPv6 link-level
+addresses, e.g. \fBssl:[fe80::1234%eth0]:6653\fR. For \fBssl\fR, the
+\fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
+options are mandatory.
.
.IP "\fBunix:\fIfile\fR"
On POSIX, connect to the Unix domain server socket named \fIfile\fR.
diff --git a/ovsdb/remote-passive.man b/ovsdb/remote-passive.man
index 5da2de87bf29..f2a1868442da 100644
--- a/ovsdb/remote-passive.man
+++ b/ovsdb/remote-passive.man
@@ -1,22 +1,15 @@
.IP "\fBpssl:\fIport\fR[\fB:\fIip\fR]"
-Listen on the given SSL \fIport\fR for a connection. By default,
-connections are not bound to a particular local IP address and
-it listens only on IPv4 (but not IPv6) addresses, but
-specifying \fIip\fR limits connections to those from the given
-\fIip\fR, either IPv4 or IPv6 address. If \fIip\fR is
-an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
-\fBpssl:6640:[::1]\fR. The \fB\-\-private\-key\fR,
-\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR options are mandatory
-when this form is used.
-.
-.IP "\fBptcp:\fIport\fR[\fB:\fIip\fR]"
-Listen on the given TCP \fIport\fR for a connection. By default,
-connections are not bound to a particular local IP address and
-it listens only on IPv4 (but not IPv6) addresses, but
-\fIip\fR may be specified to listen only for connections to the given
-\fIip\fR, either IPv4 or IPv6 address. If \fIip\fR is
-an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
-\fBptcp:6640:[::1]\fR.
+.IQ "\fBptcp:\fIport\fR[\fB:\fIip\fR]"
+Listen on the given SSL or TCP \fIport\fR for a connection. By
+default, connections are not bound to a particular local IP address
+and it listens only on IPv4 (but not IPv6) addresses, but specifying
+\fIip\fR limits connections to those from the given \fIip\fR, either
+IPv4 or IPv6 address. If \fIip\fR is an IPv6 address, then wrap
+\fIip\fR with square brackets, e.g.: \fBpssl:6640:[::1]\fR. On Linux,
+use \fB%\fIdevice\fR to designate a scope for IPv6 link-level
+addresses, e.g. \fBpssl:6653:[fe80::1234%eth0]\fR. For \fBpssl\fR,
+the \fB\-\-private\-key\fR, \fB\-\-certificate\fR, and
+\fB\-\-ca\-cert\fR options are mandatory.
.
.IP "\fBpunix:\fIfile\fR"
On POSIX, listen on the Unix domain server socket named \fIfile\fR for a
--
2.10.2
_______________________________________________
dev mailing list
dev at openvswitch.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=BVhFA09CGX7JQ5Ih-uZnsw&m=akEkPPZsOEbokZhc8suC1ou0OMIPQyhld31E2MZqJU0&s=t7TENvQoXaoiRdAGBpQ6FOFdEHczVIVWFTXppzAeBPI&e=
More information about the dev
mailing list