mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 23:05:29 +00:00
Add IPv6 support for OpenFlow, OVSDB, NetFlow, and sFlow.
Does not add IPv6 support for in-band control. Co-authored-by: Ben Pfaff <blp@nicira.com> Signed-off-by: Nandan Nivgune <nandan.nivgune@calsoftinc.com> Signed-off-by: Abhijit Bhopatkar <abhijit.bhopatkar@calsoftinc.com> Signed-off-by: Arun Sharma <arun.sharma@calsoftinc.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
1
NEWS
1
NEWS
@@ -64,6 +64,7 @@ v2.1.0 - xx xxx xxxx
|
|||||||
hard limit on the number of flows in the datapath. It defaults to 200,000
|
hard limit on the number of flows in the datapath. It defaults to 200,000
|
||||||
flows. OVS automatically adjusts this number depending on network
|
flows. OVS automatically adjusts this number depending on network
|
||||||
conditions.
|
conditions.
|
||||||
|
- Added IPv6 support for active and passive socket communications.
|
||||||
|
|
||||||
|
|
||||||
v2.0.0 - 15 Oct 2013
|
v2.0.0 - 15 Oct 2013
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2013 Nicira, Inc.
|
* Copyright (c) 2011, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -48,6 +48,15 @@ struct in6_addr {
|
|||||||
|
|
||||||
extern const struct in6_addr in6addr_any;
|
extern const struct in6_addr in6addr_any;
|
||||||
|
|
||||||
|
/* Ditto, for IPv6. */
|
||||||
|
struct sockaddr_in6 {
|
||||||
|
sa_family_t sin6_family;
|
||||||
|
in_port_t sin6_port; /* Transport layer port # */
|
||||||
|
uint32_t sin6_flowinfo; /* IPv6 flow information */
|
||||||
|
struct in6_addr sin6_addr; /* IPv6 address */
|
||||||
|
uint32_t sin6_scope_id; /* IPv6 scope-id */
|
||||||
|
};
|
||||||
|
|
||||||
#define IPPROTO_IP 0
|
#define IPPROTO_IP 0
|
||||||
#define IPPROTO_HOPOPTS 0
|
#define IPPROTO_HOPOPTS 0
|
||||||
#define IPPROTO_ICMP 1
|
#define IPPROTO_ICMP 1
|
||||||
@@ -84,6 +93,7 @@ extern const struct in6_addr in6addr_any;
|
|||||||
|
|
||||||
#define INADDR_ANY 0x00000000
|
#define INADDR_ANY 0x00000000
|
||||||
#define INADDR_BROADCAST 0xffffffff
|
#define INADDR_BROADCAST 0xffffffff
|
||||||
|
#define INADDR_LOOPBACK 0x7f000001
|
||||||
#define INADDR_NONE 0xffffffff
|
#define INADDR_NONE 0xffffffff
|
||||||
|
|
||||||
#define INET6_ADDRSTRLEN 46
|
#define INET6_ADDRSTRLEN 46
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -612,59 +612,125 @@ guess_netmask(ovs_be32 ip_)
|
|||||||
: htonl(0)); /* ??? */
|
: htonl(0)); /* ??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parses 'target', which should be a string in the format "<host>[:<port>]".
|
/* This is like strsep() except:
|
||||||
* <host> is required. If 'default_port' is nonzero then <port> is optional
|
|
||||||
* and defaults to 'default_port'.
|
|
||||||
*
|
*
|
||||||
* On success, returns true and stores the parsed remote address into '*sinp'.
|
* - The separator string is ":".
|
||||||
* On failure, logs an error, stores zeros into '*sinp', and returns false. */
|
*
|
||||||
bool
|
* - Square brackets [] quote ":" separators and are removed from the
|
||||||
inet_parse_active(const char *target_, uint16_t default_port,
|
* tokens. */
|
||||||
struct sockaddr_in *sinp)
|
static char *
|
||||||
|
parse_bracketed_token(char **pp)
|
||||||
{
|
{
|
||||||
char *target = xstrdup(target_);
|
char *p = *pp;
|
||||||
char *save_ptr = NULL;
|
|
||||||
const char *host_name;
|
|
||||||
const char *port_string;
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
/* Defaults. */
|
if (p == NULL) {
|
||||||
sinp->sin_family = AF_INET;
|
return NULL;
|
||||||
sinp->sin_port = htons(default_port);
|
} else if (*p == '\0') {
|
||||||
|
*pp = NULL;
|
||||||
|
return p;
|
||||||
|
} else if (*p == '[') {
|
||||||
|
char *start = p + 1;
|
||||||
|
char *end = start + strcspn(start, "]");
|
||||||
|
*pp = (*end == '\0' ? NULL
|
||||||
|
: end[1] == ':' ? end + 2
|
||||||
|
: end + 1);
|
||||||
|
*end = '\0';
|
||||||
|
return start;
|
||||||
|
} else {
|
||||||
|
char *start = p;
|
||||||
|
char *end = start + strcspn(start, ":");
|
||||||
|
*pp = *end == '\0' ? NULL : end + 1;
|
||||||
|
*end = '\0';
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tokenize. */
|
static bool
|
||||||
host_name = strtok_r(target, ":", &save_ptr);
|
parse_sockaddr_components(struct sockaddr_storage *ss,
|
||||||
port_string = strtok_r(NULL, ":", &save_ptr);
|
const char *host_s,
|
||||||
if (!host_name) {
|
const char *port_s, uint16_t default_port,
|
||||||
VLOG_ERR("%s: bad peer name format", target_);
|
const char *s)
|
||||||
goto exit;
|
{
|
||||||
|
struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, ss);
|
||||||
|
int port;
|
||||||
|
|
||||||
|
if (port_s && port_s[0]) {
|
||||||
|
if (!str_to_int(port_s, 10, &port) || port < 0 || port > 65535) {
|
||||||
|
VLOG_ERR("%s: bad port number \"%s\"", s, port_s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = default_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look up IP, port. */
|
memset(ss, 0, sizeof *ss);
|
||||||
if (lookup_ip(host_name, &sinp->sin_addr)) {
|
if (strchr(host_s, ':')) {
|
||||||
goto exit;
|
struct sockaddr_in6 *sin6
|
||||||
}
|
= ALIGNED_CAST(struct sockaddr_in6 *, ss);
|
||||||
if (port_string && atoi(port_string)) {
|
|
||||||
sinp->sin_port = htons(atoi(port_string));
|
sin6->sin6_family = AF_INET6;
|
||||||
} else if (!default_port) {
|
sin6->sin6_port = htons(port);
|
||||||
VLOG_ERR("%s: port number must be specified", target_);
|
if (!inet_pton(AF_INET6, host_s, sin6->sin6_addr.s6_addr)) {
|
||||||
goto exit;
|
VLOG_ERR("%s: bad IPv6 address \"%s\"", s, host_s);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
|
sin->sin_port = htons(port);
|
||||||
|
if (!inet_pton(AF_INET, host_s, &sin->sin_addr.s_addr)) {
|
||||||
|
VLOG_ERR("%s: bad IPv4 address \"%s\"", s, host_s);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = true;
|
return true;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
memset(ss, 0, sizeof *ss);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parses 'target', which should be a string in the format "<host>[:<port>]".
|
||||||
|
* <host>, which is required, may be an IPv4 address or an IPv6 address
|
||||||
|
* enclosed in square brackets. If 'default_port' is nonzero then <port> is
|
||||||
|
* optional and defaults to 'default_port'.
|
||||||
|
*
|
||||||
|
* On success, returns true and stores the parsed remote address into '*ss'.
|
||||||
|
* On failure, logs an error, stores zeros into '*ss', and returns false. */
|
||||||
|
bool
|
||||||
|
inet_parse_active(const char *target_, uint16_t default_port,
|
||||||
|
struct sockaddr_storage *ss)
|
||||||
|
{
|
||||||
|
char *target = xstrdup(target_);
|
||||||
|
const char *port;
|
||||||
|
const char *host;
|
||||||
|
char *p;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
p = target;
|
||||||
|
host = parse_bracketed_token(&p);
|
||||||
|
port = parse_bracketed_token(&p);
|
||||||
|
if (!host) {
|
||||||
|
VLOG_ERR("%s: host must be specified", target_);
|
||||||
|
ok = false;
|
||||||
|
} else if (!port && !default_port) {
|
||||||
|
VLOG_ERR("%s: port must be specified", target_);
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
ok = parse_sockaddr_components(ss, host, port, default_port, target_);
|
||||||
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
memset(sinp, 0, sizeof *sinp);
|
memset(ss, 0, sizeof *ss);
|
||||||
}
|
}
|
||||||
free(target);
|
free(target);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opens a non-blocking IPv4 socket of the specified 'style' and connects to
|
|
||||||
* 'target', which should be a string in the format "<host>[:<port>]". <host>
|
/* Opens a non-blocking IPv4 or IPv6 socket of the specified 'style' and
|
||||||
* is required. If 'default_port' is nonzero then <port> is optional and
|
* connects to 'target', which should be a string in the format
|
||||||
* defaults to 'default_port'.
|
* "<host>[:<port>]". <host>, which is required, may be an IPv4 address or an
|
||||||
|
* IPv6 address enclosed in square brackets. If 'default_port' is nonzero then
|
||||||
|
* <port> is optional and defaults to 'default_port'.
|
||||||
*
|
*
|
||||||
* 'style' should be SOCK_STREAM (for TCP) or SOCK_DGRAM (for UDP).
|
* 'style' should be SOCK_STREAM (for TCP) or SOCK_DGRAM (for UDP).
|
||||||
*
|
*
|
||||||
@@ -673,28 +739,27 @@ exit:
|
|||||||
* into '*fdp'. On failure, returns a positive errno value other than EAGAIN
|
* into '*fdp'. On failure, returns a positive errno value other than EAGAIN
|
||||||
* and stores -1 into '*fdp'.
|
* and stores -1 into '*fdp'.
|
||||||
*
|
*
|
||||||
* If 'sinp' is non-null, then on success the target address is stored into
|
* If 'ss' is non-null, then on success stores the target address into '*ss'.
|
||||||
* '*sinp'.
|
|
||||||
*
|
*
|
||||||
* 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
|
* 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
|
||||||
* should be in the range [0, 63] and will automatically be shifted to the
|
* should be in the range [0, 63] and will automatically be shifted to the
|
||||||
* appropriately place in the IP tos field. */
|
* appropriately place in the IP tos field. */
|
||||||
int
|
int
|
||||||
inet_open_active(int style, const char *target, uint16_t default_port,
|
inet_open_active(int style, const char *target, uint16_t default_port,
|
||||||
struct sockaddr_in *sinp, int *fdp, uint8_t dscp)
|
struct sockaddr_storage *ssp, int *fdp, uint8_t dscp)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_storage ss;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Parse. */
|
/* Parse. */
|
||||||
if (!inet_parse_active(target, default_port, &sin)) {
|
if (!inet_parse_active(target, default_port, &ss)) {
|
||||||
error = EAFNOSUPPORT;
|
error = EAFNOSUPPORT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create non-blocking socket. */
|
/* Create non-blocking socket. */
|
||||||
fd = socket(AF_INET, style, 0);
|
fd = socket(ss.ss_family, style, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
VLOG_ERR("%s: socket: %s", target, ovs_strerror(errno));
|
VLOG_ERR("%s: socket: %s", target, ovs_strerror(errno));
|
||||||
error = errno;
|
error = errno;
|
||||||
@@ -705,8 +770,8 @@ inet_open_active(int style, const char *target, uint16_t default_port,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The dscp bits must be configured before connect() to ensure that the TOS
|
/* The dscp bits must be configured before connect() to ensure that the
|
||||||
* field is set during the connection establishment. If set after
|
* TOS field is set during the connection establishment. If set after
|
||||||
* connect(), the handshake SYN frames will be sent with a TOS of 0. */
|
* connect(), the handshake SYN frames will be sent with a TOS of 0. */
|
||||||
error = set_dscp(fd, dscp);
|
error = set_dscp(fd, dscp);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -715,25 +780,32 @@ inet_open_active(int style, const char *target, uint16_t default_port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Connect. */
|
/* Connect. */
|
||||||
error = connect(fd, (struct sockaddr *) &sin, sizeof sin) == 0 ? 0 : errno;
|
error = connect(fd, (struct sockaddr *) &ss, ss_length(&ss)) == 0
|
||||||
|
? 0
|
||||||
|
: errno;
|
||||||
if (error == EINPROGRESS) {
|
if (error == EINPROGRESS) {
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (!error || error == EAGAIN) {
|
if (error && error != EAGAIN) {
|
||||||
if (sinp) {
|
if (ssp) {
|
||||||
*sinp = sin;
|
memset(ssp, 0, sizeof *ssp);
|
||||||
|
}
|
||||||
|
if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ssp) {
|
||||||
|
*ssp = ss;
|
||||||
}
|
}
|
||||||
} else if (fd >= 0) {
|
|
||||||
close(fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
}
|
||||||
*fdp = fd;
|
*fdp = fd;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parses 'target', which should be a string in the format "[<port>][:<ip>]":
|
/* Parses 'target', which should be a string in the format "[<port>][:<host>]":
|
||||||
*
|
*
|
||||||
* - If 'default_port' is -1, then <port> is required. Otherwise, if
|
* - If 'default_port' is -1, then <port> is required. Otherwise, if
|
||||||
* <port> is omitted, then 'default_port' is used instead.
|
* <port> is omitted, then 'default_port' is used instead.
|
||||||
@@ -741,54 +813,41 @@ exit:
|
|||||||
* - If <port> (or 'default_port', if used) is 0, then no port is bound
|
* - If <port> (or 'default_port', if used) is 0, then no port is bound
|
||||||
* and the TCP/IP stack will select a port.
|
* and the TCP/IP stack will select a port.
|
||||||
*
|
*
|
||||||
* - If <ip> is omitted then the IP address is wildcarded.
|
* - <host> is optional. If supplied, it may be an IPv4 address or an
|
||||||
|
* IPv6 address enclosed in square brackets. If omitted, the IP address
|
||||||
|
* is wildcarded.
|
||||||
*
|
*
|
||||||
* If successful, stores the address into '*sinp' and returns true; otherwise
|
* If successful, stores the address into '*ss' and returns true; otherwise
|
||||||
* zeros '*sinp' and returns false. */
|
* zeros '*ss' and returns false. */
|
||||||
bool
|
bool
|
||||||
inet_parse_passive(const char *target_, int default_port,
|
inet_parse_passive(const char *target_, int default_port,
|
||||||
struct sockaddr_in *sinp)
|
struct sockaddr_storage *ss)
|
||||||
{
|
{
|
||||||
char *target = xstrdup(target_);
|
char *target = xstrdup(target_);
|
||||||
char *string_ptr = target;
|
const char *port;
|
||||||
const char *host_name;
|
const char *host;
|
||||||
const char *port_string;
|
char *p;
|
||||||
bool ok = false;
|
bool ok;
|
||||||
int port;
|
|
||||||
|
|
||||||
/* Address defaults. */
|
p = target;
|
||||||
memset(sinp, 0, sizeof *sinp);
|
port = parse_bracketed_token(&p);
|
||||||
sinp->sin_family = AF_INET;
|
host = parse_bracketed_token(&p);
|
||||||
sinp->sin_addr.s_addr = htonl(INADDR_ANY);
|
if (!port && default_port < 0) {
|
||||||
sinp->sin_port = htons(default_port);
|
VLOG_ERR("%s: port must be specified", target_);
|
||||||
|
ok = false;
|
||||||
/* Parse optional port number. */
|
} else {
|
||||||
port_string = strsep(&string_ptr, ":");
|
ok = parse_sockaddr_components(ss, host ? host : "0.0.0.0",
|
||||||
if (port_string && str_to_int(port_string, 10, &port)) {
|
port, default_port, target_);
|
||||||
sinp->sin_port = htons(port);
|
|
||||||
} else if (default_port < 0) {
|
|
||||||
VLOG_ERR("%s: port number must be specified", target_);
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse optional bind IP. */
|
|
||||||
host_name = strsep(&string_ptr, ":");
|
|
||||||
if (host_name && host_name[0] && lookup_ip(host_name, &sinp->sin_addr)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = true;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
memset(sinp, 0, sizeof *sinp);
|
memset(ss, 0, sizeof *ss);
|
||||||
}
|
}
|
||||||
free(target);
|
free(target);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opens a non-blocking IPv4 socket of the specified 'style', binds to
|
/* Opens a non-blocking IPv4 or IPv6 socket of the specified 'style', binds to
|
||||||
* 'target', and listens for incoming connections. Parses 'target' in the same
|
* 'target', and listens for incoming connections. Parses 'target' in the same
|
||||||
* way was inet_parse_passive().
|
* way was inet_parse_passive().
|
||||||
*
|
*
|
||||||
@@ -799,27 +858,27 @@ exit:
|
|||||||
* On success, returns a non-negative file descriptor. On failure, returns a
|
* On success, returns a non-negative file descriptor. On failure, returns a
|
||||||
* negative errno value.
|
* negative errno value.
|
||||||
*
|
*
|
||||||
* If 'sinp' is non-null, then on success the bound address is stored into
|
* If 'ss' is non-null, then on success stores the bound address into '*ss'.
|
||||||
* '*sinp'.
|
|
||||||
*
|
*
|
||||||
* 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
|
* 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
|
||||||
* should be in the range [0, 63] and will automatically be shifted to the
|
* should be in the range [0, 63] and will automatically be shifted to the
|
||||||
* appropriately place in the IP tos field. */
|
* appropriately place in the IP tos field. */
|
||||||
int
|
int
|
||||||
inet_open_passive(int style, const char *target, int default_port,
|
inet_open_passive(int style, const char *target, int default_port,
|
||||||
struct sockaddr_in *sinp, uint8_t dscp)
|
struct sockaddr_storage *ssp, uint8_t dscp)
|
||||||
{
|
{
|
||||||
bool kernel_chooses_port;
|
bool kernel_chooses_port;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_storage ss;
|
||||||
int fd = 0, error;
|
int fd = 0, error;
|
||||||
unsigned int yes = 1;
|
unsigned int yes = 1;
|
||||||
|
|
||||||
if (!inet_parse_passive(target, default_port, &sin)) {
|
if (!inet_parse_passive(target, default_port, &ss)) {
|
||||||
return -EAFNOSUPPORT;
|
return -EAFNOSUPPORT;
|
||||||
}
|
}
|
||||||
|
kernel_chooses_port = ss_get_port(&ss) == 0;
|
||||||
|
|
||||||
/* Create non-blocking socket, set SO_REUSEADDR. */
|
/* Create non-blocking socket, set SO_REUSEADDR. */
|
||||||
fd = socket(AF_INET, style, 0);
|
fd = socket(ss.ss_family, style, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
error = errno;
|
error = errno;
|
||||||
VLOG_ERR("%s: socket: %s", target, ovs_strerror(error));
|
VLOG_ERR("%s: socket: %s", target, ovs_strerror(error));
|
||||||
@@ -838,7 +897,7 @@ inet_open_passive(int style, const char *target, int default_port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Bind. */
|
/* Bind. */
|
||||||
if (bind(fd, (struct sockaddr *) &sin, sizeof sin) < 0) {
|
if (bind(fd, (struct sockaddr *) &ss, ss_length(&ss)) < 0) {
|
||||||
error = errno;
|
error = errno;
|
||||||
VLOG_ERR("%s: bind: %s", target, ovs_strerror(error));
|
VLOG_ERR("%s: bind: %s", target, ovs_strerror(error));
|
||||||
goto error;
|
goto error;
|
||||||
@@ -860,31 +919,28 @@ inet_open_passive(int style, const char *target, int default_port,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel_chooses_port = sin.sin_port == htons(0);
|
if (ssp || kernel_chooses_port) {
|
||||||
if (sinp || kernel_chooses_port) {
|
socklen_t ss_len = sizeof ss;
|
||||||
socklen_t sin_len = sizeof sin;
|
if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) < 0) {
|
||||||
if (getsockname(fd, (struct sockaddr *) &sin, &sin_len) < 0) {
|
|
||||||
error = errno;
|
error = errno;
|
||||||
VLOG_ERR("%s: getsockname: %s", target, ovs_strerror(error));
|
VLOG_ERR("%s: getsockname: %s", target, ovs_strerror(error));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (sin.sin_family != AF_INET || sin_len != sizeof sin) {
|
|
||||||
error = EAFNOSUPPORT;
|
|
||||||
VLOG_ERR("%s: getsockname: invalid socket name", target);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (sinp) {
|
|
||||||
*sinp = sin;
|
|
||||||
}
|
|
||||||
if (kernel_chooses_port) {
|
if (kernel_chooses_port) {
|
||||||
VLOG_INFO("%s: listening on port %"PRIu16,
|
VLOG_INFO("%s: listening on port %"PRIu16,
|
||||||
target, ntohs(sin.sin_port));
|
target, ss_get_port(&ss));
|
||||||
|
}
|
||||||
|
if (ssp) {
|
||||||
|
*ssp = ss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
if (ssp) {
|
||||||
|
memset(ssp, 0, sizeof *ssp);
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
return -error;
|
return -error;
|
||||||
}
|
}
|
||||||
@@ -1060,12 +1116,12 @@ describe_sockaddr(struct ds *string, int fd,
|
|||||||
socklen_t len = sizeof ss;
|
socklen_t len = sizeof ss;
|
||||||
|
|
||||||
if (!getaddr(fd, (struct sockaddr *) &ss, &len)) {
|
if (!getaddr(fd, (struct sockaddr *) &ss, &len)) {
|
||||||
if (ss.ss_family == AF_INET) {
|
if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
|
||||||
struct sockaddr_in sin;
|
char addrbuf[SS_NTOP_BUFSIZE];
|
||||||
|
|
||||||
memcpy(&sin, &ss, sizeof sin);
|
ds_put_format(string, "%s:%"PRIu16,
|
||||||
ds_put_format(string, IP_FMT":%"PRIu16,
|
ss_format_address(&ss, addrbuf, sizeof addrbuf),
|
||||||
IP_ARGS(sin.sin_addr.s_addr), ntohs(sin.sin_port));
|
ss_get_port(&ss));
|
||||||
} else if (ss.ss_family == AF_UNIX) {
|
} else if (ss.ss_family == AF_UNIX) {
|
||||||
struct sockaddr_un sun;
|
struct sockaddr_un sun;
|
||||||
const char *null;
|
const char *null;
|
||||||
@@ -1225,4 +1281,66 @@ af_inet_ifreq_ioctl(const char *name, struct ifreq *ifr, unsigned long int cmd,
|
|||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sockaddr_storage helpers. */
|
||||||
|
|
||||||
|
/* Returns the IPv4 or IPv6 port in 'ss'. */
|
||||||
|
uint16_t
|
||||||
|
ss_get_port(const struct sockaddr_storage *ss)
|
||||||
|
{
|
||||||
|
if (ss->ss_family == AF_INET) {
|
||||||
|
const struct sockaddr_in *sin
|
||||||
|
= ALIGNED_CAST(const struct sockaddr_in *, ss);
|
||||||
|
return ntohs(sin->sin_port);
|
||||||
|
} else if (ss->ss_family == AF_INET6) {
|
||||||
|
const struct sockaddr_in6 *sin6
|
||||||
|
= ALIGNED_CAST(const struct sockaddr_in6 *, ss);
|
||||||
|
return ntohs(sin6->sin6_port);
|
||||||
|
} else {
|
||||||
|
OVS_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Formats the IPv4 or IPv6 address in 'ss' into the 'bufsize' bytes in 'buf'.
|
||||||
|
* If 'ss' is an IPv6 address, puts square brackets around the address.
|
||||||
|
* 'bufsize' should be at least SS_NTOP_BUFSIZE.
|
||||||
|
*
|
||||||
|
* Returns 'buf'. */
|
||||||
|
char *
|
||||||
|
ss_format_address(const struct sockaddr_storage *ss,
|
||||||
|
char *buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
ovs_assert(bufsize >= SS_NTOP_BUFSIZE);
|
||||||
|
if (ss->ss_family == AF_INET) {
|
||||||
|
const struct sockaddr_in *sin
|
||||||
|
= ALIGNED_CAST(const struct sockaddr_in *, ss);
|
||||||
|
|
||||||
|
snprintf(buf, bufsize, IP_FMT, IP_ARGS(sin->sin_addr.s_addr));
|
||||||
|
} else if (ss->ss_family == AF_INET6) {
|
||||||
|
const struct sockaddr_in6 *sin6
|
||||||
|
= ALIGNED_CAST(const struct sockaddr_in6 *, ss);
|
||||||
|
|
||||||
|
buf[0] = '[';
|
||||||
|
inet_ntop(AF_INET6, sin6->sin6_addr.s6_addr, buf + 1, bufsize - 1);
|
||||||
|
strcpy(strchr(buf, '\0'), "]");
|
||||||
|
} else {
|
||||||
|
OVS_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
ss_length(const struct sockaddr_storage *ss)
|
||||||
|
{
|
||||||
|
switch (ss->ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
return sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
return sizeof(struct sockaddr_in6);
|
||||||
|
|
||||||
|
default:
|
||||||
|
OVS_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -48,14 +48,14 @@ ovs_be32 guess_netmask(ovs_be32 ip);
|
|||||||
int get_null_fd(void);
|
int get_null_fd(void);
|
||||||
|
|
||||||
bool inet_parse_active(const char *target, uint16_t default_port,
|
bool inet_parse_active(const char *target, uint16_t default_port,
|
||||||
struct sockaddr_in *sinp);
|
struct sockaddr_storage *ssp);
|
||||||
int inet_open_active(int style, const char *target, uint16_t default_port,
|
int inet_open_active(int style, const char *target, uint16_t default_port,
|
||||||
struct sockaddr_in *sinp, int *fdp, uint8_t dscp);
|
struct sockaddr_storage *ssp, int *fdp, uint8_t dscp);
|
||||||
|
|
||||||
bool inet_parse_passive(const char *target, int default_port,
|
bool inet_parse_passive(const char *target, int default_port,
|
||||||
struct sockaddr_in *sinp);
|
struct sockaddr_storage *ssp);
|
||||||
int inet_open_passive(int style, const char *target, int default_port,
|
int inet_open_passive(int style, const char *target, int default_port,
|
||||||
struct sockaddr_in *sinp, uint8_t dscp);
|
struct sockaddr_storage *ssp, uint8_t dscp);
|
||||||
|
|
||||||
int read_fully(int fd, void *, size_t, size_t *bytes_read);
|
int read_fully(int fd, void *, size_t, size_t *bytes_read);
|
||||||
int write_fully(int fd, const void *, size_t, size_t *bytes_written);
|
int write_fully(int fd, const void *, size_t, size_t *bytes_written);
|
||||||
@@ -79,4 +79,12 @@ int af_inet_ioctl(unsigned long int command, const void *arg);
|
|||||||
int af_inet_ifreq_ioctl(const char *name, struct ifreq *,
|
int af_inet_ifreq_ioctl(const char *name, struct ifreq *,
|
||||||
unsigned long int cmd, const char *cmd_name);
|
unsigned long int cmd, const char *cmd_name);
|
||||||
|
|
||||||
|
/* Functions for working with sockaddr_storage that might contain an IPv4 or
|
||||||
|
* IPv6 address. */
|
||||||
|
uint16_t ss_get_port(const struct sockaddr_storage *);
|
||||||
|
#define SS_NTOP_BUFSIZE (1 + INET6_ADDRSTRLEN + 1)
|
||||||
|
char *ss_format_address(const struct sockaddr_storage *,
|
||||||
|
char *buf, size_t bufsize);
|
||||||
|
size_t ss_length(const struct sockaddr_storage *);
|
||||||
|
|
||||||
#endif /* socket-util.h */
|
#endif /* socket-util.h */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -148,7 +148,7 @@ struct fd_pstream
|
|||||||
{
|
{
|
||||||
struct pstream pstream;
|
struct pstream pstream;
|
||||||
int fd;
|
int fd;
|
||||||
int (*accept_cb)(int fd, const struct sockaddr *, size_t sa_len,
|
int (*accept_cb)(int fd, const struct sockaddr_storage *, size_t ss_len,
|
||||||
struct stream **);
|
struct stream **);
|
||||||
int (*set_dscp_cb)(int fd, uint8_t dscp);
|
int (*set_dscp_cb)(int fd, uint8_t dscp);
|
||||||
char *unlink_path;
|
char *unlink_path;
|
||||||
@@ -179,8 +179,8 @@ fd_pstream_cast(struct pstream *pstream)
|
|||||||
* implementation never fails.) */
|
* implementation never fails.) */
|
||||||
int
|
int
|
||||||
new_fd_pstream(const char *name, int fd,
|
new_fd_pstream(const char *name, int fd,
|
||||||
int (*accept_cb)(int fd, const struct sockaddr *sa,
|
int (*accept_cb)(int fd, const struct sockaddr_storage *ss,
|
||||||
size_t sa_len, struct stream **streamp),
|
size_t ss_len, struct stream **streamp),
|
||||||
int (*set_dscp_cb)(int fd, uint8_t dscp),
|
int (*set_dscp_cb)(int fd, uint8_t dscp),
|
||||||
char *unlink_path, struct pstream **pstreamp)
|
char *unlink_path, struct pstream **pstreamp)
|
||||||
{
|
{
|
||||||
@@ -227,8 +227,7 @@ pfd_accept(struct pstream *pstream, struct stream **new_streamp)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps->accept_cb(new_fd, (const struct sockaddr *) &ss, ss_len,
|
return ps->accept_cb(new_fd, &ss, ss_len, new_streamp);
|
||||||
new_streamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2012 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2012, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,13 +23,13 @@
|
|||||||
|
|
||||||
struct stream;
|
struct stream;
|
||||||
struct pstream;
|
struct pstream;
|
||||||
struct sockaddr;
|
struct sockaddr_storage;
|
||||||
|
|
||||||
int new_fd_stream(const char *name, int fd, int connect_status,
|
int new_fd_stream(const char *name, int fd, int connect_status,
|
||||||
struct stream **streamp);
|
struct stream **streamp);
|
||||||
int new_fd_pstream(const char *name, int fd,
|
int new_fd_pstream(const char *name, int fd,
|
||||||
int (*accept_cb)(int fd, const struct sockaddr *,
|
int (*accept_cb)(int fd, const struct sockaddr_storage *ss,
|
||||||
size_t sa_len, struct stream **),
|
size_t ss_len, struct stream **),
|
||||||
int (*set_dscp_cb)(int fd, uint8_t dscp),
|
int (*set_dscp_cb)(int fd, uint8_t dscp),
|
||||||
char *unlink_path,
|
char *unlink_path,
|
||||||
struct pstream **pstreamp);
|
struct pstream **pstreamp);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -206,7 +206,7 @@ static int
|
|||||||
new_ssl_stream(const char *name, int fd, enum session_type type,
|
new_ssl_stream(const char *name, int fd, enum session_type type,
|
||||||
enum ssl_state state, struct stream **streamp)
|
enum ssl_state state, struct stream **streamp)
|
||||||
{
|
{
|
||||||
struct sockaddr_in local;
|
struct sockaddr_storage local;
|
||||||
socklen_t local_len = sizeof local;
|
socklen_t local_len = sizeof local;
|
||||||
struct ssl_stream *sslv;
|
struct ssl_stream *sslv;
|
||||||
SSL *ssl = NULL;
|
SSL *ssl = NULL;
|
||||||
@@ -780,9 +780,11 @@ static int
|
|||||||
pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
|
pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
|
||||||
uint8_t dscp)
|
uint8_t dscp)
|
||||||
{
|
{
|
||||||
|
char bound_name[SS_NTOP_BUFSIZE + 16];
|
||||||
|
char addrbuf[SS_NTOP_BUFSIZE];
|
||||||
|
struct sockaddr_storage ss;
|
||||||
struct pssl_pstream *pssl;
|
struct pssl_pstream *pssl;
|
||||||
struct sockaddr_in sin;
|
uint16_t port;
|
||||||
char bound_name[128];
|
|
||||||
int retval;
|
int retval;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@@ -791,16 +793,18 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = inet_open_passive(SOCK_STREAM, suffix, OFP_OLD_PORT, &sin, dscp);
|
fd = inet_open_passive(SOCK_STREAM, suffix, OFP_OLD_PORT, &ss, dscp);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return -fd;
|
return -fd;
|
||||||
}
|
}
|
||||||
sprintf(bound_name, "pssl:%"PRIu16":"IP_FMT,
|
|
||||||
ntohs(sin.sin_port), IP_ARGS(sin.sin_addr.s_addr));
|
port = ss_get_port(&ss);
|
||||||
|
snprintf(bound_name, sizeof bound_name, "ptcp:%"PRIu16":%s",
|
||||||
|
port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
|
||||||
|
|
||||||
pssl = xmalloc(sizeof *pssl);
|
pssl = xmalloc(sizeof *pssl);
|
||||||
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
|
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
|
||||||
pstream_set_bound_port(&pssl->pstream, sin.sin_port);
|
pstream_set_bound_port(&pssl->pstream, htons(port));
|
||||||
pssl->fd = fd;
|
pssl->fd = fd;
|
||||||
*pstreamp = &pssl->pstream;
|
*pstreamp = &pssl->pstream;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -818,13 +822,14 @@ static int
|
|||||||
pssl_accept(struct pstream *pstream, struct stream **new_streamp)
|
pssl_accept(struct pstream *pstream, struct stream **new_streamp)
|
||||||
{
|
{
|
||||||
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
|
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
|
||||||
struct sockaddr_in sin;
|
char name[SS_NTOP_BUFSIZE + 16];
|
||||||
socklen_t sin_len = sizeof sin;
|
char addrbuf[SS_NTOP_BUFSIZE];
|
||||||
char name[128];
|
struct sockaddr_storage ss;
|
||||||
|
socklen_t ss_len = sizeof ss;
|
||||||
int new_fd;
|
int new_fd;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
new_fd = accept(pssl->fd, (struct sockaddr *) &sin, &sin_len);
|
new_fd = accept(pssl->fd, (struct sockaddr *) &ss, &ss_len);
|
||||||
if (new_fd < 0) {
|
if (new_fd < 0) {
|
||||||
error = errno;
|
error = errno;
|
||||||
if (error != EAGAIN) {
|
if (error != EAGAIN) {
|
||||||
@@ -839,10 +844,9 @@ pssl_accept(struct pstream *pstream, struct stream **new_streamp)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(name, "ssl:"IP_FMT, IP_ARGS(sin.sin_addr.s_addr));
|
snprintf(name, sizeof name, "tcp:%s:%"PRIu16,
|
||||||
if (sin.sin_port != htons(OFP_OLD_PORT)) {
|
ss_format_address(&ss, addrbuf, sizeof addrbuf),
|
||||||
sprintf(strchr(name, '\0'), ":%"PRIu16, ntohs(sin.sin_port));
|
ss_get_port(&ss));
|
||||||
}
|
|
||||||
return new_ssl_stream(name, new_fd, SERVER, STATE_SSL_CONNECTING,
|
return new_ssl_stream(name, new_fd, SERVER, STATE_SSL_CONNECTING,
|
||||||
new_streamp);
|
new_streamp);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -21,10 +21,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "dynamic-string.h"
|
||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -40,13 +42,13 @@ static int
|
|||||||
new_tcp_stream(const char *name, int fd, int connect_status,
|
new_tcp_stream(const char *name, int fd, int connect_status,
|
||||||
struct stream **streamp)
|
struct stream **streamp)
|
||||||
{
|
{
|
||||||
struct sockaddr_in local;
|
struct sockaddr_storage local;
|
||||||
socklen_t local_len = sizeof local;
|
socklen_t local_len = sizeof local;
|
||||||
int on = 1;
|
int on = 1;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Get the local IP and port information */
|
/* Get the local IP and port information */
|
||||||
retval = getsockname(fd, (struct sockaddr *)&local, &local_len);
|
retval = getsockname(fd, (struct sockaddr *) &local, &local_len);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
memset(&local, 0, sizeof local);
|
memset(&local, 0, sizeof local);
|
||||||
}
|
}
|
||||||
@@ -90,47 +92,47 @@ const struct stream_class tcp_stream_class = {
|
|||||||
|
|
||||||
/* Passive TCP. */
|
/* Passive TCP. */
|
||||||
|
|
||||||
static int ptcp_accept(int fd, const struct sockaddr *sa, size_t sa_len,
|
static int ptcp_accept(int fd, const struct sockaddr_storage *,
|
||||||
struct stream **streamp);
|
size_t, struct stream **streamp);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
|
ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
|
||||||
uint8_t dscp)
|
uint8_t dscp)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
char bound_name[SS_NTOP_BUFSIZE + 16];
|
||||||
char bound_name[128];
|
char addrbuf[SS_NTOP_BUFSIZE];
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
uint16_t port;
|
||||||
int error;
|
int error;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = inet_open_passive(SOCK_STREAM, suffix, -1, &sin, dscp);
|
fd = inet_open_passive(SOCK_STREAM, suffix, -1, &ss, dscp);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return -fd;
|
return -fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(bound_name, "ptcp:%"PRIu16":"IP_FMT,
|
port = ss_get_port(&ss);
|
||||||
ntohs(sin.sin_port), IP_ARGS(sin.sin_addr.s_addr));
|
snprintf(bound_name, sizeof bound_name, "ptcp:%"PRIu16":%s",
|
||||||
|
port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
|
||||||
|
|
||||||
error = new_fd_pstream(bound_name, fd, ptcp_accept, set_dscp, NULL,
|
error = new_fd_pstream(bound_name, fd, ptcp_accept, set_dscp, NULL,
|
||||||
pstreamp);
|
pstreamp);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
pstream_set_bound_port(*pstreamp, sin.sin_port);
|
pstream_set_bound_port(*pstreamp, htons(port));
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ptcp_accept(int fd, const struct sockaddr *sa, size_t sa_len,
|
ptcp_accept(int fd, const struct sockaddr_storage *ss,
|
||||||
struct stream **streamp)
|
size_t ss_len OVS_UNUSED, struct stream **streamp)
|
||||||
{
|
{
|
||||||
const struct sockaddr_in *sin = ALIGNED_CAST(const struct sockaddr_in *,
|
char name[SS_NTOP_BUFSIZE + 16];
|
||||||
sa);
|
char addrbuf[SS_NTOP_BUFSIZE];
|
||||||
char name[128];
|
|
||||||
|
|
||||||
if (sa_len == sizeof(struct sockaddr_in) && sin->sin_family == AF_INET) {
|
snprintf(name, sizeof name, "tcp:%s:%"PRIu16,
|
||||||
sprintf(name, "tcp:"IP_FMT, IP_ARGS(sin->sin_addr.s_addr));
|
ss_format_address(ss, addrbuf, sizeof addrbuf),
|
||||||
sprintf(strchr(name, '\0'), ":%"PRIu16, ntohs(sin->sin_port));
|
ss_get_port(ss));
|
||||||
} else {
|
|
||||||
strcpy(name, "tcp");
|
|
||||||
}
|
|
||||||
return new_tcp_stream(name, fd, 0, streamp);
|
return new_tcp_stream(name, fd, 0, streamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -75,8 +75,8 @@ const struct stream_class unix_stream_class = {
|
|||||||
|
|
||||||
/* Passive UNIX socket. */
|
/* Passive UNIX socket. */
|
||||||
|
|
||||||
static int punix_accept(int fd, const struct sockaddr *sa, size_t sa_len,
|
static int punix_accept(int fd, const struct sockaddr_storage *ss,
|
||||||
struct stream **streamp);
|
size_t ss_len, struct stream **streamp);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
punix_open(const char *name OVS_UNUSED, char *suffix,
|
punix_open(const char *name OVS_UNUSED, char *suffix,
|
||||||
@@ -105,11 +105,11 @@ punix_open(const char *name OVS_UNUSED, char *suffix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
punix_accept(int fd, const struct sockaddr *sa, size_t sa_len,
|
punix_accept(int fd, const struct sockaddr_storage *ss, size_t ss_len,
|
||||||
struct stream **streamp)
|
struct stream **streamp)
|
||||||
{
|
{
|
||||||
const struct sockaddr_un *sun = (const struct sockaddr_un *) sa;
|
const struct sockaddr_un *sun = (const struct sockaddr_un *) ss;
|
||||||
int name_len = get_unix_name_len(sa_len);
|
int name_len = get_unix_name_len(ss_len);
|
||||||
char name[128];
|
char name[128];
|
||||||
|
|
||||||
if (name_len > 0) {
|
if (name_len > 0) {
|
||||||
|
@@ -720,18 +720,18 @@ pstream_open_with_default_port(const char *name_,
|
|||||||
/*
|
/*
|
||||||
* This function extracts IP address and port from the target string.
|
* This function extracts IP address and port from the target string.
|
||||||
*
|
*
|
||||||
* - On success, function returns true and fills *sin structure with port
|
* - On success, function returns true and fills *ss structure with port
|
||||||
* and IP address. If port was absent in target string then it will use
|
* and IP address. If port was absent in target string then it will use
|
||||||
* corresponding default port value.
|
* corresponding default port value.
|
||||||
* - On error, function returns false and *sin contains garbage.
|
* - On error, function returns false and *ss contains garbage.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
stream_parse_target_with_default_port(const char *target,
|
stream_parse_target_with_default_port(const char *target,
|
||||||
uint16_t default_port,
|
uint16_t default_port,
|
||||||
struct sockaddr_in *sin)
|
struct sockaddr_storage *ss)
|
||||||
{
|
{
|
||||||
return ((!strncmp(target, "tcp:", 4) || !strncmp(target, "ssl:", 4))
|
return ((!strncmp(target, "tcp:", 4) || !strncmp(target, "ssl:", 4))
|
||||||
&& inet_parse_active(target + 4, default_port, sin));
|
&& inet_parse_active(target + 4, default_port, ss));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempts to guess the content type of a stream whose first few bytes were
|
/* Attempts to guess the content type of a stream whose first few bytes were
|
||||||
|
@@ -81,7 +81,7 @@ int pstream_open_with_default_port(const char *name,
|
|||||||
uint8_t dscp);
|
uint8_t dscp);
|
||||||
bool stream_parse_target_with_default_port(const char *target,
|
bool stream_parse_target_with_default_port(const char *target,
|
||||||
uint16_t default_port,
|
uint16_t default_port,
|
||||||
struct sockaddr_in *sin);
|
struct sockaddr_storage *ss);
|
||||||
int stream_or_pstream_needs_probes(const char *name);
|
int stream_or_pstream_needs_probes(const char *name);
|
||||||
|
|
||||||
/* Error reporting. */
|
/* Error reporting. */
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
.IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
|
.IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
|
||||||
.IQ "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
|
.IQ "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
|
||||||
The specified \fIport\fR on the host at the given \fIip\fR, which must
|
The specified \fIport\fR on the host at the given \fIip\fR, which must
|
||||||
be expressed as an IP address (not a DNS name). For \fBssl\fR, the
|
be expressed as an IP address (not a DNS name) in IPv4 or IPv6 address
|
||||||
\fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
|
format. Wrap IPv6 addresses in square brackets,
|
||||||
options are mandatory.
|
e.g. \fBtcp:[::1]:6633\fR. For \fBssl\fR, the \fB\-\-private\-key\fR,
|
||||||
|
\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR options are mandatory.
|
||||||
.IP
|
.IP
|
||||||
If \fIport\fR is not specified, it currently defaults to 6633. In the
|
If \fIport\fR is not specified, it currently defaults to 6633. In the
|
||||||
future, the default will change to 6653, which is the IANA-defined
|
future, the default will change to 6653, which is the IANA-defined
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
.IP "\fBpssl:\fR[\fIport\fR][\fB:\fIip\fR]"
|
.IP "\fBpssl:\fR[\fIport\fR][\fB:\fIip\fR]"
|
||||||
.IQ "\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]"
|
.IQ "\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]"
|
||||||
Listens for OpenFlow connections on \fIport\fR. By
|
Listens for OpenFlow connections on \fIport\fR. The default
|
||||||
default, connections are not bound to a particular local IP address, but
|
\fIport\fR is 6633, but a future version of Open vSwitch will change
|
||||||
\fIip\fR may be specified to listen only for connections to the given
|
the default to the IANA-defined port 6653. By default, connections
|
||||||
\fIip\fR. For \fBpssl\fR, the \fB\-\-private\-key\fR,
|
are allowed from any IPv4 address. Specify \fIip\fR as an IPv4
|
||||||
\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR options are mandatory.
|
address or a bracketed IPv6 address (e.g. \fBptcp:6633:[::1]\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
|
.IP
|
||||||
If \fIport\fR is not specified, it currently defaults to 6633. In the
|
|
||||||
future, the default will change to 6653, which is the IANA-defined
|
|
||||||
value.
|
|
||||||
.
|
.
|
||||||
.IP "\fBpunix:\fIfile\fR"
|
.IP "\fBpunix:\fIfile\fR"
|
||||||
Listens for OpenFlow connections on the Unix domain server socket
|
Listens for OpenFlow connections on the Unix domain server socket
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -734,17 +734,13 @@ update_in_band_remotes(struct connmgr *mgr)
|
|||||||
|
|
||||||
/* Add all the remotes. */
|
/* Add all the remotes. */
|
||||||
HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
|
HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
|
||||||
struct sockaddr_in *sin = &addrs[n_addrs];
|
|
||||||
const char *target = rconn_get_target(ofconn->rconn);
|
const char *target = rconn_get_target(ofconn->rconn);
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
|
||||||
if (ofconn->band == OFPROTO_OUT_OF_BAND) {
|
if (ofconn->band == OFPROTO_IN_BAND
|
||||||
continue;
|
&& stream_parse_target_with_default_port(target, OFP_OLD_PORT, &ss)
|
||||||
}
|
&& ss.ss_family == AF_INET) {
|
||||||
|
addrs[n_addrs++] = *(struct sockaddr_in *) &ss;
|
||||||
if (stream_parse_target_with_default_port(target,
|
|
||||||
OFP_OLD_PORT,
|
|
||||||
sin)) {
|
|
||||||
n_addrs++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < mgr->n_extra_remotes; i++) {
|
for (i = 0; i < mgr->n_extra_remotes; i++) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
* Copyright (c) 2009 InMon Corp.
|
* Copyright (c) 2009 InMon Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -253,13 +253,16 @@ sflow_choose_agent_address(const char *agent_device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSET_FOR_EACH (target, targets) {
|
SSET_FOR_EACH (target, targets) {
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_storage ss;
|
||||||
char name[IFNAMSIZ];
|
char name[IFNAMSIZ];
|
||||||
|
|
||||||
if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &sin)
|
if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &ss)
|
||||||
&& route_table_get_name(sin.sin_addr.s_addr, name)
|
&& ss.ss_family == AF_INET) {
|
||||||
&& !netdev_get_in4_by_name(name, &in4)) {
|
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
|
||||||
goto success;
|
if (route_table_get_name(sin->sin_addr.s_addr, name)
|
||||||
|
&& !netdev_get_in4_by_name(name, &in4)) {
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
.IP "\fBssl:\fIip\fB:\fIport\fR"
|
.IP "\fBssl:\fIip\fB:\fIport\fR"
|
||||||
The specified SSL \fIport\fR on the host at the given \fIip\fR, which
|
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). The
|
must be expressed as an IP address (not a DNS name) in IPv4 or IPv6 address
|
||||||
\fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
|
format. If \fIip\fR is an IPv6 address, then wrap \fIip\fR with square
|
||||||
|
brackets, e.g.: \fBssl:[::1]:6632\fR.
|
||||||
|
The \fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
|
||||||
options are mandatory when this form is used.
|
options are mandatory when this form is used.
|
||||||
.
|
.
|
||||||
.IP "\fBtcp:\fIip\fB:\fIport\fR"
|
.IP "\fBtcp:\fIip\fB:\fIport\fR"
|
||||||
Connect to the given TCP \fIport\fR on \fIip\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]:6632\fR.
|
||||||
.
|
.
|
||||||
.IP "\fBunix:\fIfile\fR"
|
.IP "\fBunix:\fIfile\fR"
|
||||||
Connect to the Unix domain server socket named \fIfile\fR.
|
Connect to the Unix domain server socket named \fIfile\fR.
|
||||||
|
@@ -1,15 +1,22 @@
|
|||||||
.IP "\fBpssl:\fIport\fR[\fB:\fIip\fR]"
|
.IP "\fBpssl:\fIport\fR[\fB:\fIip\fR]"
|
||||||
Listen on the given SSL \fIport\fR for a connection. By default,
|
Listen on the given SSL \fIport\fR for a connection. By default,
|
||||||
connections are not bound to a particular local IP address, but
|
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
|
specifying \fIip\fR limits connections to those from the given
|
||||||
\fIip\fR. The \fB\-\-private\-key\fR, \fB\-\-certificate\fR, and
|
\fIip\fR, either IPv4 or IPv6 address. If \fIip\fR is
|
||||||
\fB\-\-ca\-cert\fR options are mandatory when this form is used.
|
an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
|
||||||
|
\fBpssl:6632:[::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]"
|
.IP "\fBptcp:\fIport\fR[\fB:\fIip\fR]"
|
||||||
Listen on the given TCP \fIport\fR for a connection. By default,
|
Listen on the given TCP \fIport\fR for a connection. By default,
|
||||||
connections are not bound to a particular local IP address, but
|
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 may be specified to listen only for connections to the given
|
||||||
\fIip\fR.
|
\fIip\fR, either IPv4 or IPv6 address. If \fIip\fR is
|
||||||
|
an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
|
||||||
|
\fBptcp:6632:[::1]\fR.
|
||||||
.
|
.
|
||||||
.IP "\fBpunix:\fIfile\fR"
|
.IP "\fBpunix:\fIfile\fR"
|
||||||
Listen on the Unix domain server socket named \fIfile\fR for a
|
Listen on the Unix domain server socket named \fIfile\fR for a
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2010, 2012 Nicira, Inc.
|
# Copyright (c) 2010, 2012, 2014 Nicira, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -177,24 +177,44 @@ def check_connection_completion(sock):
|
|||||||
return errno.EAGAIN
|
return errno.EAGAIN
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_ipv4_address(address):
|
||||||
|
try:
|
||||||
|
socket.inet_pton(socket.AF_INET, address)
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
socket.inet_aton(address)
|
||||||
|
except socket.error:
|
||||||
|
return False
|
||||||
|
except socket.error:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def inet_parse_active(target, default_port):
|
def inet_parse_active(target, default_port):
|
||||||
address = target.split(":")
|
address = target.split(":")
|
||||||
host_name = address[0]
|
if len(address) >= 2:
|
||||||
|
host_name = ":".join(address[0:-1]).lstrip('[').rstrip(']')
|
||||||
|
port = int(address[-1])
|
||||||
|
else:
|
||||||
|
if default_port:
|
||||||
|
port = default_port
|
||||||
|
else:
|
||||||
|
raise ValueError("%s: port number must be specified" % target)
|
||||||
|
host_name = address[0]
|
||||||
if not host_name:
|
if not host_name:
|
||||||
raise ValueError("%s: bad peer name format" % target)
|
raise ValueError("%s: bad peer name format" % target)
|
||||||
if len(address) >= 2:
|
|
||||||
port = int(address[1])
|
|
||||||
elif default_port:
|
|
||||||
port = default_port
|
|
||||||
else:
|
|
||||||
raise ValueError("%s: port number must be specified" % target)
|
|
||||||
return (host_name, port)
|
return (host_name, port)
|
||||||
|
|
||||||
|
|
||||||
def inet_open_active(style, target, default_port, dscp):
|
def inet_open_active(style, target, default_port, dscp):
|
||||||
address = inet_parse_active(target, default_port)
|
address = inet_parse_active(target, default_port)
|
||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_INET, style, 0)
|
is_addr_inet = is_valid_ipv4_address(address[0])
|
||||||
|
if is_addr_inet:
|
||||||
|
sock = socket.socket(socket.AF_INET, style, 0)
|
||||||
|
else:
|
||||||
|
sock = socket.socket(socket.AF_INET6, style, 0)
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
return get_exception_errno(e), None
|
return get_exception_errno(e), None
|
||||||
|
|
||||||
|
@@ -1829,55 +1829,58 @@ AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\{1,\}$/?/' | sort],
|
|||||||
OVS_VSWITCHD_STOP
|
OVS_VSWITCHD_STOP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
dnl Test that sFlow samples packets correctly.
|
# CHECK_SFLOW_SAMPLING_PACKET(LOOPBACK_ADDR, ADDR_WITHOUT_BRACKETS)
|
||||||
AT_SETUP([ofproto-dpif - sFlow packet sampling])
|
#
|
||||||
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
# Test that sFlow samples packets correctly using IPv4/IPv6 sFlow collector
|
||||||
|
#
|
||||||
|
# IP_VERSION_TYPE is used in AT_SETUP
|
||||||
|
m4_define([CHECK_SFLOW_SAMPLING_PACKET],
|
||||||
|
[AT_SETUP([ofproto-dpif - sFlow packet sampling - $2 collector])
|
||||||
|
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
||||||
|
|
||||||
ON_EXIT([kill `cat test-sflow.pid`])
|
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_CHECK([test-sflow --log-file --detach --no-chdir --pidfile 0:$1 > sflow.log], [0], [], [ignore])
|
||||||
AT_CAPTURE_FILE([sflow.log])
|
AT_CAPTURE_FILE([sflow.log])
|
||||||
SFLOW_PORT=`parse_listening_port < test-sflow.log`
|
SFLOW_PORT=`parse_listening_port < test-sflow.log`
|
||||||
|
ovs-appctl time/stop
|
||||||
|
|
||||||
ovs-appctl time/stop
|
ADD_OF_PORTS([br0], 1, 2)
|
||||||
|
ovs-vsctl \
|
||||||
|
set Interface br0 options:ifindex=1002 -- \
|
||||||
|
set Interface p1 options:ifindex=1004 -- \
|
||||||
|
set Interface p2 options:ifindex=1003 -- \
|
||||||
|
set Bridge br0 sflow=@sf -- \
|
||||||
|
--id=@sf create sflow targets=\"$1:$SFLOW_PORT\" \
|
||||||
|
header=128 sampling=1 polling=1 agent=lo
|
||||||
|
|
||||||
ADD_OF_PORTS([br0], 1, 2)
|
dnl open with ARP packets to seed the bridge-learning. The output
|
||||||
ovs-vsctl \
|
dnl ifIndex numbers should be reported predictably after that.
|
||||||
set Interface br0 options:ifindex=1002 -- \
|
dnl Since we set sampling=1 we should see all of these packets
|
||||||
set Interface p1 options:ifindex=1004 -- \
|
dnl reported. Sorting the output by data-source and seqNo makes
|
||||||
set Interface p2 options:ifindex=1003 -- \
|
dnl it deterministic. Ensuring that we send at least two packets
|
||||||
set Bridge br0 sflow=@sf -- \
|
dnl into each port means we get to check the seq nos are
|
||||||
--id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" \
|
dnl incrementing correctly.
|
||||||
header=128 sampling=1 polling=1
|
dnl because packets from different ports can be handled by separate
|
||||||
|
dnl threads, put some sleeps
|
||||||
|
|
||||||
dnl open with ARP packets to seed the bridge-learning. The output
|
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=FF:FF:FF:FF:FF:FF),eth_type(0x0806),arp(sip=192.168.0.2,tip=192.168.0.1,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)'
|
||||||
dnl ifIndex numbers should be reported predictably after that.
|
sleep 1
|
||||||
dnl Since we set sampling=1 we should see all of these packets
|
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=FF:FF:FF:FF:FF:FF),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:07,tha=00:00:00:00:00:00)'
|
||||||
dnl reported. Sorting the output by data-source and seqNo makes
|
sleep 1
|
||||||
dnl it deterministic. Ensuring that we send at least two packets
|
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
|
||||||
dnl into each port means we get to check the seq nos are
|
sleep 1
|
||||||
dnl incrementing correctly.
|
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)'
|
||||||
|
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x86dd),ipv6(src=fe80::1,dst=fe80::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'
|
||||||
|
|
||||||
dnl because packets from different ports can be handled by separate
|
dnl sleep long enough to get more than one counter sample
|
||||||
dnl threads, put some sleeps
|
dnl from each datasource so we can check sequence numbers
|
||||||
|
for i in `seq 1 30`; do
|
||||||
|
ovs-appctl time/warp 100
|
||||||
|
done
|
||||||
|
OVS_VSWITCHD_STOP
|
||||||
|
ovs-appctl -t test-sflow exit
|
||||||
|
|
||||||
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=FF:FF:FF:FF:FF:FF),eth_type(0x0806),arp(sip=192.168.0.2,tip=192.168.0.1,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)'
|
AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 's/ /\
|
||||||
sleep 1
|
|
||||||
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=FF:FF:FF:FF:FF:FF),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:07,tha=00:00:00:00:00:00)'
|
|
||||||
sleep 1
|
|
||||||
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
|
|
||||||
sleep 1
|
|
||||||
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)'
|
|
||||||
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x86dd),ipv6(src=fe80::1,dst=fe80::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'
|
|
||||||
|
|
||||||
dnl sleep long enough to get more than one counter sample
|
|
||||||
dnl from each datasource so we can check sequence numbers
|
|
||||||
for i in `seq 1 30`; do
|
|
||||||
ovs-appctl time/warp 100
|
|
||||||
done
|
|
||||||
OVS_VSWITCHD_STOP
|
|
||||||
ovs-appctl -t test-sflow exit
|
|
||||||
|
|
||||||
AT_CHECK([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 's/ /\
|
|
||||||
/g']], [0], [dnl
|
/g']], [0], [dnl
|
||||||
HEADER
|
HEADER
|
||||||
dgramSeqNo=1
|
dgramSeqNo=1
|
||||||
@@ -1981,7 +1984,7 @@ HEADER
|
|||||||
hdr=50-54-00-00-00-05-50-54-00-00-00-07-86-DD-67-00-00-00-00-00-0A-80-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-01-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-02-00-00-00-00-00-00
|
hdr=50-54-00-00-00-05-50-54-00-00-00-07-86-DD-67-00-00-00-00-00-0A-80-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-01-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-02-00-00-00-00-00-00
|
||||||
])
|
])
|
||||||
|
|
||||||
AT_CHECK([[sort sflow.log | $EGREP 'IFCOUNTERS|ERROR' | head -6 | sed 's/ /\
|
AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'IFCOUNTERS|ERROR' | head -6 | sed 's/ /\
|
||||||
/g']], [0], [dnl
|
/g']], [0], [dnl
|
||||||
IFCOUNTERS
|
IFCOUNTERS
|
||||||
dgramSeqNo=2
|
dgramSeqNo=2
|
||||||
@@ -2122,128 +2125,144 @@ IFCOUNTERS
|
|||||||
out_errors=0
|
out_errors=0
|
||||||
promiscuous=0
|
promiscuous=0
|
||||||
])
|
])
|
||||||
AT_CLEANUP
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
CHECK_SFLOW_SAMPLING_PACKET([127.0.0.1], [IPv4])
|
||||||
|
CHECK_SFLOW_SAMPLING_PACKET([[[::1]]], [IPv6])
|
||||||
|
|
||||||
|
# CHECK_NETFLOW_EXPIRATION(LOOPBACK_ADDR, IP_VERSION_TYPE)
|
||||||
|
#
|
||||||
|
# Test that basic NetFlow reports flow statistics correctly:
|
||||||
|
# The initial packet of a flow are correctly accounted.
|
||||||
|
# Later packets within a flow are correctly accounted.
|
||||||
|
# Flow actions changing (in this case, due to MAC learning)
|
||||||
|
# cause a record to be sent.
|
||||||
|
#
|
||||||
|
# IP_VERSION_TYPE is used in AT_SETUP
|
||||||
|
m4_define([CHECK_NETFLOW_EXPIRATION],
|
||||||
|
[AT_SETUP([ofproto-dpif - NetFlow flow expiration - $2 collector])
|
||||||
|
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
||||||
|
ADD_OF_PORTS([br0], 1, 2)
|
||||||
|
|
||||||
dnl Test that basic NetFlow reports flow statistics correctly:
|
ovs-appctl time/stop
|
||||||
dnl - The initial packet of a flow are correctly accounted.
|
ON_EXIT([kill `cat test-netflow.pid`])
|
||||||
dnl - Later packets within a flow are correctly accounted.
|
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:$1 > netflow.log], [0], [], [ignore])
|
||||||
dnl - Flow actions changing (in this case, due to MAC learning)
|
AT_CAPTURE_FILE([netflow.log])
|
||||||
dnl cause a record to be sent.
|
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
||||||
AT_SETUP([ofproto-dpif - NetFlow flow expiration])
|
|
||||||
|
|
||||||
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
ovs-vsctl \
|
||||||
ADD_OF_PORTS([br0], 1, 2)
|
set Bridge br0 netflow=@nf -- \
|
||||||
|
--id=@nf create NetFlow targets=\"$1:$NETFLOW_PORT\" \
|
||||||
|
engine_id=1 engine_type=2 active_timeout=30 add-id-to-interface=false
|
||||||
|
|
||||||
ovs-appctl time/stop
|
for delay in 1000 30000; do
|
||||||
ON_EXIT([kill `cat test-netflow.pid`])
|
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
|
||||||
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > netflow.log], [0], [], [ignore])
|
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)'
|
||||||
AT_CAPTURE_FILE([netflow.log])
|
|
||||||
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
|
||||||
|
|
||||||
ovs-vsctl \
|
ovs-appctl time/warp $delay
|
||||||
set Bridge br0 netflow=@nf -- \
|
done
|
||||||
--id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
|
|
||||||
engine_id=1 engine_type=2 active_timeout=30 add-id-to-interface=false
|
|
||||||
|
|
||||||
for delay in 1000 30000; do
|
ovs-appctl time/warp 6000
|
||||||
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
|
sleep 1
|
||||||
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)'
|
OVS_VSWITCHD_STOP
|
||||||
|
ovs-appctl -t test-netflow exit
|
||||||
|
|
||||||
ovs-appctl time/warp $delay
|
AT_CHECK([test `grep "192.168.0.1 > 192.168.0.2, if 1 > 65535, 1 pkts, 60 bytes, ICMP 8:0" netflow.log | wc -l` -eq 1])
|
||||||
done
|
|
||||||
|
|
||||||
ovs-appctl time/warp 6000
|
AT_CHECK([test `grep "192.168.0.1 > 192.168.0.2, if 1 > 2, 1 pkts, 60 bytes, ICMP 8:0" netflow.log | wc -l` -eq 1])
|
||||||
sleep 1
|
|
||||||
OVS_VSWITCHD_STOP
|
|
||||||
ovs-appctl -t test-netflow exit
|
|
||||||
|
|
||||||
AT_CHECK([test `grep "192.168.0.1 > 192.168.0.2, if 1 > 65535, 1 pkts, 60 bytes, ICMP 8:0" netflow.log | wc -l` -eq 1])
|
combined=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 2 pkts, 120 bytes, ICMP 0:0" netflow.log | wc -l`
|
||||||
|
separate=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 1 pkts, 60 bytes, ICMP 0:0" netflow.log | wc -l`
|
||||||
|
AT_CHECK([test $separate = 2 || test $combined = 1], [0])
|
||||||
|
|
||||||
AT_CHECK([test `grep "192.168.0.1 > 192.168.0.2, if 1 > 2, 1 pkts, 60 bytes, ICMP 8:0" netflow.log | wc -l` -eq 1])
|
AT_CLEANUP])
|
||||||
|
|
||||||
combined=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 2 pkts, 120 bytes, ICMP 0:0" netflow.log | wc -l`
|
CHECK_NETFLOW_EXPIRATION([127.0.0.1], [IPv4])
|
||||||
separate=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 1 pkts, 60 bytes, ICMP 0:0" netflow.log | wc -l`
|
CHECK_NETFLOW_EXPIRATION([[[::1]]], [IPv6])
|
||||||
AT_CHECK([test $separate = 2 || test $combined = 1], [0])
|
|
||||||
|
|
||||||
AT_CLEANUP
|
# CHECK_NETFLOW_ACTIVE_EXPIRATION(LOOPBACK_ADDR, IP_VERSION_TYPE)
|
||||||
|
#
|
||||||
|
# Test that basic NetFlow reports active expirations correctly.
|
||||||
|
#
|
||||||
|
# IP_VERSION_TYPE is used in AT_SETUP
|
||||||
|
m4_define([CHECK_NETFLOW_ACTIVE_EXPIRATION],
|
||||||
|
[AT_SETUP([ofproto-dpif - NetFlow active expiration - $2 collector])
|
||||||
|
|
||||||
dnl Test that basic NetFlow reports active expirations correctly.
|
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
||||||
AT_SETUP([ofproto-dpif - NetFlow active expiration])
|
ADD_OF_PORTS([br0], 1, 2)
|
||||||
|
|
||||||
OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
|
ON_EXIT([kill `cat test-netflow.pid`])
|
||||||
ADD_OF_PORTS([br0], 1, 2)
|
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:$1 > netflow.log], [0], [], [ignore])
|
||||||
|
AT_CAPTURE_FILE([netflow.log])
|
||||||
|
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
||||||
|
|
||||||
ON_EXIT([kill `cat test-netflow.pid`])
|
ovs-vsctl \
|
||||||
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > netflow.log], [0], [], [ignore])
|
set Bridge br0 netflow=@nf -- \
|
||||||
AT_CAPTURE_FILE([netflow.log])
|
--id=@nf create NetFlow targets=\"$1:$NETFLOW_PORT\" \
|
||||||
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
engine_id=1 engine_type=2 active_timeout=10 add-id-to-interface=false
|
||||||
|
|
||||||
ovs-vsctl \
|
AT_CHECK([ovs-appctl time/stop])
|
||||||
set Bridge br0 netflow=@nf -- \
|
n=1
|
||||||
--id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
|
while test $n -le 60; do
|
||||||
engine_id=1 engine_type=2 active_timeout=10 add-id-to-interface=false
|
n=`expr $n + 1`
|
||||||
|
|
||||||
AT_CHECK([ovs-appctl time/stop])
|
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=1234,dst=80)'
|
||||||
n=1
|
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=1234)'
|
||||||
while test $n -le 60; do
|
|
||||||
n=`expr $n + 1`
|
|
||||||
|
|
||||||
ovs-appctl netdev-dummy/receive p1 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=1234,dst=80)'
|
ovs-appctl time/warp 1000
|
||||||
ovs-appctl netdev-dummy/receive p2 'in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=1234)'
|
done
|
||||||
|
|
||||||
ovs-appctl time/warp 1000
|
ovs-appctl time/warp 10000
|
||||||
done
|
|
||||||
|
|
||||||
ovs-appctl time/warp 10000
|
sleep 1
|
||||||
|
OVS_VSWITCHD_STOP
|
||||||
|
ovs-appctl -t test-netflow exit
|
||||||
|
|
||||||
sleep 1
|
# Count the number of reported packets:
|
||||||
OVS_VSWITCHD_STOP
|
# - From source to destination before MAC learning kicks in (just one).
|
||||||
ovs-appctl -t test-netflow exit
|
# - From source to destination after that.
|
||||||
|
# - From destination to source.
|
||||||
|
n_learn=0
|
||||||
|
n_in=0
|
||||||
|
n_out=0
|
||||||
|
n_other=0
|
||||||
|
n_recs=0
|
||||||
|
none=0
|
||||||
|
while read line; do
|
||||||
|
pkts=`echo "$line" | sed 's/.*, \([[0-9]]*\) pkts,.*/\1/'`
|
||||||
|
case $pkts in
|
||||||
|
[[0-9]]*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Count the number of reported packets:
|
case $line in
|
||||||
# - From source to destination before MAC learning kicks in (just one).
|
"seq "*": 192.168.0.1 > 192.168.0.2, if 1 > 65535, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
|
||||||
# - From source to destination after that.
|
counter=n_learn
|
||||||
# - From destination to source.
|
;;
|
||||||
n_learn=0
|
"seq "*": 192.168.0.1 > 192.168.0.2, if 1 > 2, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
|
||||||
n_in=0
|
counter=n_in
|
||||||
n_out=0
|
;;
|
||||||
n_other=0
|
"seq "*": 192.168.0.2 > 192.168.0.1, if 2 > 1, "*" pkts, "*" bytes, TCP 80 > 1234, time "*)
|
||||||
n_recs=0
|
counter=n_out
|
||||||
none=0
|
;;
|
||||||
while read line; do
|
*)
|
||||||
pkts=`echo "$line" | sed 's/.*, \([[0-9]]*\) pkts,.*/\1/'`
|
counter=n_other
|
||||||
case $pkts in
|
;;
|
||||||
[[0-9]]*) ;;
|
esac
|
||||||
*) continue ;;
|
eval $counter=\`expr \$$counter + \$pkts\`
|
||||||
esac
|
n_recs=`expr $n_recs + 1`
|
||||||
|
done < netflow.log
|
||||||
|
|
||||||
case $line in
|
# There should be exactly 1 MAC learning packet,
|
||||||
"seq "*": 192.168.0.1 > 192.168.0.2, if 1 > 65535, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
|
# exactly 59 other packets in that direction,
|
||||||
counter=n_learn
|
# and exactly 60 packets in the other direction.
|
||||||
;;
|
AT_CHECK([echo $n_learn $n_in $n_out $n_other], [0], [1 59 60 0
|
||||||
"seq "*": 192.168.0.1 > 192.168.0.2, if 1 > 2, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
|
|
||||||
counter=n_in
|
|
||||||
;;
|
|
||||||
"seq "*": 192.168.0.2 > 192.168.0.1, if 2 > 1, "*" pkts, "*" bytes, TCP 80 > 1234, time "*)
|
|
||||||
counter=n_out
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
counter=n_other
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
eval $counter=\`expr \$$counter + \$pkts\`
|
|
||||||
n_recs=`expr $n_recs + 1`
|
|
||||||
done < netflow.log
|
|
||||||
|
|
||||||
# There should be exactly 1 MAC learning packet,
|
|
||||||
# exactly 59 other packets in that direction,
|
|
||||||
# and exactly 60 packets in the other direction.
|
|
||||||
AT_CHECK([echo $n_learn $n_in $n_out $n_other], [0], [1 59 60 0
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
CHECK_NETFLOW_ACTIVE_EXPIRATION([127.0.0.1], [IPv4])
|
||||||
|
CHECK_NETFLOW_ACTIVE_EXPIRATION([[[::1]]], [IPv6])
|
||||||
|
|
||||||
AT_SETUP([idle_age and hard_age increase over time])
|
AT_SETUP([idle_age and hard_age increase over time])
|
||||||
OVS_VSWITCHD_START
|
OVS_VSWITCHD_START
|
||||||
@@ -2700,30 +2719,37 @@ skb_priority(0),in_port(1),eth(src=50:54:00:00:00:0b/ff:ff:ff:ff:ff:ff,dst=50:54
|
|||||||
OVS_VSWITCHD_STOP
|
OVS_VSWITCHD_STOP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
AT_SETUP([ofproto-dpif megaflow - netflow])
|
# CHECK_MEGAFLOW_NETFLOW(LOOPBACK_ADDR, IP_VERSION_TYPE)
|
||||||
OVS_VSWITCHD_START
|
#
|
||||||
ADD_OF_PORTS([br0], [1], [2])
|
# IP_VERSION_TYPE is used in AT_SETUP
|
||||||
|
m4_define([CHECK_MEGAFLOW_NETFLOW],
|
||||||
|
[AT_SETUP([ofproto-dpif megaflow - netflow - $2 collector])
|
||||||
|
OVS_VSWITCHD_START
|
||||||
|
ADD_OF_PORTS([br0], [1], [2])
|
||||||
|
|
||||||
dnl NetFlow configuration disables wildcarding relevant fields
|
dnl NetFlow configuration disables wildcarding relevant fields
|
||||||
ON_EXIT([kill `cat test-netflow.pid`])
|
ON_EXIT([kill `cat test-netflow.pid`])
|
||||||
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > netflow.log], [0], [], [ignore])
|
AT_CHECK([test-netflow --log-file --detach --no-chdir --pidfile 0:$1 > netflow.log], [0], [], [ignore])
|
||||||
AT_CAPTURE_FILE([netflow.log])
|
AT_CAPTURE_FILE([netflow.log])
|
||||||
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
NETFLOW_PORT=`parse_listening_port < test-netflow.log`
|
||||||
ovs-vsctl \
|
ovs-vsctl \
|
||||||
set Bridge br0 netflow=@nf -- \
|
set Bridge br0 netflow=@nf -- \
|
||||||
--id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
|
--id=@nf create NetFlow targets=\"$1:$NETFLOW_PORT\" \
|
||||||
engine_id=1 engine_type=2 active_timeout=30 add-id-to-interface=false
|
engine_id=1 engine_type=2 active_timeout=30 add-id-to-interface=false
|
||||||
|
|
||||||
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
|
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
|
||||||
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
|
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
|
||||||
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
|
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
|
||||||
sleep 1
|
sleep 1
|
||||||
AT_CHECK([ovs-appctl dpif/dump-flows br0 | STRIP_XOUT], [0], [dnl
|
AT_CHECK([ovs-appctl dpif/dump-flows br0 | STRIP_XOUT], [0], [dnl
|
||||||
skb_priority(0),in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2/255.255.255.255,dst=10.0.0.1/255.255.255.255,proto=1/0xff,tos=0/0xfc,ttl=64/0,frag=no/0xff),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions: <del>
|
skb_priority(0),in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2/255.255.255.255,dst=10.0.0.1/255.255.255.255,proto=1/0xff,tos=0/0xfc,ttl=64/0,frag=no/0xff),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions: <del>
|
||||||
skb_priority(0),in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4/255.255.255.255,dst=10.0.0.3/255.255.255.255,proto=1/0xff,tos=0/0xfc,ttl=64/0,frag=no/0xff),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions: <del>
|
skb_priority(0),in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4/255.255.255.255,dst=10.0.0.3/255.255.255.255,proto=1/0xff,tos=0/0xfc,ttl=64/0,frag=no/0xff),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions: <del>
|
||||||
])
|
])
|
||||||
OVS_VSWITCHD_STOP
|
OVS_VSWITCHD_STOP
|
||||||
AT_CLEANUP
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
CHECK_MEGAFLOW_NETFLOW([127.0.0.1], [IPv4])
|
||||||
|
CHECK_MEGAFLOW_NETFLOW([[[::1]]], [IPv6])
|
||||||
|
|
||||||
AT_SETUP([ofproto-dpif megaflow - normal, active-backup bonding])
|
AT_SETUP([ofproto-dpif megaflow - normal, active-backup bonding])
|
||||||
OVS_VSWITCHD_START(
|
OVS_VSWITCHD_START(
|
||||||
|
@@ -21,7 +21,7 @@ s/ hard_age=[0-9]*,//
|
|||||||
# log, given that the server was told to listen on a kernel-chosen
|
# 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.
|
# 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
|
# You should specify the listening remote as ptcp:0:127.0.0.1 or
|
||||||
# pssl:0:127.0.0.1.
|
# pssl:0:127.0.0.1, or the equivalent with [::1] instead of 127.0.0.1.
|
||||||
#
|
#
|
||||||
# Here's an example of how to use this with ovsdb-server:
|
# Here's an example of how to use this with ovsdb-server:
|
||||||
#
|
#
|
||||||
@@ -29,7 +29,7 @@ s/ hard_age=[0-9]*,//
|
|||||||
# ovsdb-server --log-file --remote=ptcp:0:127.0.0.1 ...
|
# ovsdb-server --log-file --remote=ptcp:0:127.0.0.1 ...
|
||||||
# TCP_PORT=`parse_listening_port < ovsdb-server.log`
|
# TCP_PORT=`parse_listening_port < ovsdb-server.log`
|
||||||
parse_listening_port () {
|
parse_listening_port () {
|
||||||
sed -n 's/.*0:127\.0\.0\.1: listening on port \([0-9]*\)$/\1/p'
|
sed -n 's/.*0:.*: listening on port \([0-9]*\)$/\1/p'
|
||||||
}]
|
}]
|
||||||
m4_divert_pop([PREPARE_TESTS])
|
m4_divert_pop([PREPARE_TESTS])
|
||||||
|
|
||||||
|
@@ -177,7 +177,7 @@ OVSDB_CHECK_EXECUTION([duplicate uuid-name not allowed],
|
|||||||
[[[{"uuid":["uuid","<0>"]},{"details":"This \"uuid-name\" appeared on an earlier \"insert\" operation.","error":"duplicate uuid-name","syntax":"\"x\""}]
|
[[[{"uuid":["uuid","<0>"]},{"details":"This \"uuid-name\" appeared on an earlier \"insert\" operation.","error":"duplicate uuid-name","syntax":"\"x\""}]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
m4_define([EXECUTION_EXAMPLES], [
|
m4_define([ONE_EXECUTION_EXAMPLE], [dnl
|
||||||
dnl At one point the "commit" code ignored new rows with all-default values,
|
dnl At one point the "commit" code ignored new rows with all-default values,
|
||||||
dnl so this checks for that problem.
|
dnl so this checks for that problem.
|
||||||
OVSDB_CHECK_EXECUTION([insert default row, query table],
|
OVSDB_CHECK_EXECUTION([insert default row, query table],
|
||||||
@@ -193,7 +193,10 @@ OVSDB_CHECK_EXECUTION([insert default row, query table],
|
|||||||
[[[{"uuid":["uuid","<0>"]}]
|
[[[{"uuid":["uuid","<0>"]}]
|
||||||
[{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"","number":0}]}]
|
[{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"","number":0}]}]
|
||||||
]])
|
]])
|
||||||
|
])
|
||||||
|
|
||||||
|
m4_define([EXECUTION_EXAMPLES], [
|
||||||
|
ONE_EXECUTION_EXAMPLE
|
||||||
OVSDB_CHECK_EXECUTION([insert row, query table],
|
OVSDB_CHECK_EXECUTION([insert row, query table],
|
||||||
[ordinal_schema],
|
[ordinal_schema],
|
||||||
[[[["ordinals",
|
[[[["ordinals",
|
||||||
|
@@ -72,10 +72,33 @@ m4_define([OVSDB_CHECK_IDL_TCP_PY],
|
|||||||
OVSDB_SERVER_SHUTDOWN
|
OVSDB_SERVER_SHUTDOWN
|
||||||
AT_CLEANUP])
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
# same as OVSDB_CHECK_IDL but uses the Python IDL implementation with tcp6
|
||||||
|
m4_define([OVSDB_CHECK_IDL_TCP6_PY],
|
||||||
|
[AT_SETUP([$1 - Python tcp6])
|
||||||
|
AT_SKIP_IF([test $HAVE_PYTHON = no])
|
||||||
|
AT_KEYWORDS([ovsdb server idl positive Python with tcp6 socket $5])
|
||||||
|
OVS_RUNDIR=`pwd`; export OVS_RUNDIR
|
||||||
|
OVS_LOGDIR=`pwd`; export OVS_LOGDIR
|
||||||
|
AT_CHECK([ovsdb-tool create db $abs_srcdir/idltest.ovsschema],
|
||||||
|
[0], [stdout], [ignore])
|
||||||
|
AT_CHECK([ovsdb-server --log-file '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=ptcp:0:[[::1]] --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
|
||||||
|
TCP_PORT=`parse_listening_port < ovsdb-server.log`
|
||||||
|
echo "TCP_PORT=$TCP_PORT"
|
||||||
|
|
||||||
|
m4_if([$2], [], [],
|
||||||
|
[AT_CHECK([ovsdb-client transact "tcp:[[::1]]:$TCP_PORT" $2], [0], [ignore], [ignore], [kill `cat pid`])])
|
||||||
|
AT_CHECK([strace $PYTHON $srcdir/test-ovsdb.py -t10 idl $srcdir/idltest.ovsschema tcp:[[::1]]:$TCP_PORT $3],
|
||||||
|
[0], [stdout], [ignore], [kill `cat pid`])
|
||||||
|
AT_CHECK([sort stdout | ${PERL} $srcdir/uuidfilt.pl]m4_if([$6],,, [[| $6]]),
|
||||||
|
[0], [$4], [], [kill `cat pid`])
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
m4_define([OVSDB_CHECK_IDL],
|
m4_define([OVSDB_CHECK_IDL],
|
||||||
[OVSDB_CHECK_IDL_C($@)
|
[OVSDB_CHECK_IDL_C($@)
|
||||||
OVSDB_CHECK_IDL_PY($@)
|
OVSDB_CHECK_IDL_PY($@)
|
||||||
OVSDB_CHECK_IDL_TCP_PY($@)])
|
OVSDB_CHECK_IDL_TCP_PY($@)
|
||||||
|
OVSDB_CHECK_IDL_TCP6_PY($@)])
|
||||||
|
|
||||||
OVSDB_CHECK_IDL([simple idl, initially empty, no ops],
|
OVSDB_CHECK_IDL([simple idl, initially empty, no ops],
|
||||||
[],
|
[],
|
||||||
|
@@ -748,7 +748,7 @@ for i in `seq 1 100`; do
|
|||||||
done
|
done
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
AT_BANNER([OVSDB -- ovsdb-server transactions (SSL sockets)])
|
AT_BANNER([OVSDB -- ovsdb-server transactions (SSL IPv4 sockets)])
|
||||||
|
|
||||||
# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
|
# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
|
||||||
#
|
#
|
||||||
@@ -787,7 +787,46 @@ cat stdout >> output
|
|||||||
|
|
||||||
EXECUTION_EXAMPLES
|
EXECUTION_EXAMPLES
|
||||||
|
|
||||||
AT_BANNER([OVSDB -- ovsdb-server transactions (TCP sockets)])
|
AT_BANNER([OVSDB -- ovsdb-server transactions (SSL IPv6 sockets)])
|
||||||
|
|
||||||
|
# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
|
||||||
|
#
|
||||||
|
# Creates a database with the given SCHEMA, starts an ovsdb-server on
|
||||||
|
# that database, and runs each of the TRANSACTIONS (which should be a
|
||||||
|
# quoted list of quoted strings) against it with ovsdb-client one at a
|
||||||
|
# time.
|
||||||
|
#
|
||||||
|
# Checks that the overall output is OUTPUT, but UUIDs in the output
|
||||||
|
# are replaced by markers of the form <N> where N is a number. The
|
||||||
|
# first unique UUID is replaced by <0>, the next by <1>, and so on.
|
||||||
|
# If a given UUID appears more than once it is always replaced by the
|
||||||
|
# same marker.
|
||||||
|
#
|
||||||
|
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
|
||||||
|
m4_define([OVSDB_CHECK_EXECUTION],
|
||||||
|
[AT_SETUP([$1])
|
||||||
|
AT_KEYWORDS([ovsdb server positive ssl6 $5])
|
||||||
|
AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
|
||||||
|
OVS_RUNDIR=`pwd`; export OVS_RUNDIR
|
||||||
|
OVS_LOGDIR=`pwd`; export OVS_LOGDIR
|
||||||
|
$2 > schema
|
||||||
|
PKIDIR=$abs_top_builddir/tests
|
||||||
|
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
|
||||||
|
AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:0:[[::1]] --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
|
||||||
|
SSL_PORT=`parse_listening_port < ovsdb-server.log`
|
||||||
|
m4_foreach([txn], [$3],
|
||||||
|
[AT_CHECK([ovsdb-client --private-key=$PKIDIR/testpki-privkey.pem --certificate=$PKIDIR/testpki-cert.pem --ca-cert=$PKIDIR/testpki-cacert.pem transact ssl:[[::1]]:$SSL_PORT 'txn'], [0], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`])
|
||||||
|
cat stdout >> output
|
||||||
|
])
|
||||||
|
AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [$4], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`])
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
ONE_EXECUTION_EXAMPLE
|
||||||
|
|
||||||
|
AT_BANNER([OVSDB -- ovsdb-server transactions (TCP IPv4 sockets)])
|
||||||
|
|
||||||
AT_SETUP([ovsdb-client get-schema-version - tcp socket])
|
AT_SETUP([ovsdb-client get-schema-version - tcp socket])
|
||||||
AT_KEYWORDS([ovsdb server positive tcp])
|
AT_KEYWORDS([ovsdb server positive tcp])
|
||||||
@@ -836,6 +875,42 @@ cat stdout >> output
|
|||||||
AT_CLEANUP])
|
AT_CLEANUP])
|
||||||
|
|
||||||
EXECUTION_EXAMPLES
|
EXECUTION_EXAMPLES
|
||||||
|
|
||||||
|
# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
|
||||||
|
#
|
||||||
|
# Creates a database with the given SCHEMA, starts an ovsdb-server on
|
||||||
|
# that database, and runs each of the TRANSACTIONS (which should be a
|
||||||
|
# quoted list of quoted strings) against it with ovsdb-client one at a
|
||||||
|
# time.
|
||||||
|
#
|
||||||
|
# Checks that the overall output is OUTPUT, but UUIDs in the output
|
||||||
|
# are replaced by markers of the form <N> where N is a number. The
|
||||||
|
# first unique UUID is replaced by <0>, the next by <1>, and so on.
|
||||||
|
# If a given UUID appears more than once it is always replaced by the
|
||||||
|
# same marker.
|
||||||
|
#
|
||||||
|
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
|
||||||
|
m4_define([OVSDB_CHECK_EXECUTION],
|
||||||
|
[AT_SETUP([$1])
|
||||||
|
AT_KEYWORDS([ovsdb server positive tcp6 $5])
|
||||||
|
OVS_RUNDIR=`pwd`; export OVS_RUNDIR
|
||||||
|
OVS_LOGDIR=`pwd`; export OVS_LOGDIR
|
||||||
|
$2 > schema
|
||||||
|
PKIDIR=$abs_top_builddir/tests
|
||||||
|
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
|
||||||
|
AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --remote=ptcp:0:[[::1]] --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
|
||||||
|
TCP_PORT=`parse_listening_port < ovsdb-server.log`
|
||||||
|
m4_foreach([txn], [$3],
|
||||||
|
[AT_CHECK([ovsdb-client transact tcp:[[::1]]:$TCP_PORT 'txn'], [0], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`])
|
||||||
|
cat stdout >> output
|
||||||
|
])
|
||||||
|
AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [$4], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`])
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
ONE_EXECUTION_EXAMPLE
|
||||||
|
|
||||||
AT_BANNER([OVSDB -- transactions on transient ovsdb-server])
|
AT_BANNER([OVSDB -- transactions on transient ovsdb-server])
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013 Nicira, Inc.
|
* Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||||
* Copyright (c) 2013 InMon Corp.
|
* Copyright (c) 2013 InMon Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -44,7 +44,6 @@ static unixctl_cb_func test_sflow_exit;
|
|||||||
/* Datagram. */
|
/* Datagram. */
|
||||||
#define SFLOW_VERSION_5 5
|
#define SFLOW_VERSION_5 5
|
||||||
#define SFLOW_MIN_LEN 36
|
#define SFLOW_MIN_LEN 36
|
||||||
#define SFLOW_MAX_AGENTIP_STRLEN 64
|
|
||||||
|
|
||||||
/* Sample tag numbers. */
|
/* Sample tag numbers. */
|
||||||
#define SFLOW_FLOW_SAMPLE 1
|
#define SFLOW_FLOW_SAMPLE 1
|
||||||
@@ -82,7 +81,7 @@ struct sflow_xdr {
|
|||||||
|
|
||||||
/* Agent. */
|
/* Agent. */
|
||||||
struct sflow_addr agentAddr;
|
struct sflow_addr agentAddr;
|
||||||
char agentIPStr[SFLOW_MAX_AGENTIP_STRLEN];
|
char agentIPStr[INET6_ADDRSTRLEN + 2];
|
||||||
uint32_t subAgentId;
|
uint32_t subAgentId;
|
||||||
uint32_t uptime_mS;
|
uint32_t uptime_mS;
|
||||||
|
|
||||||
@@ -325,14 +324,12 @@ process_datagram(struct sflow_xdr *x)
|
|||||||
|
|
||||||
/* Store the agent address as a string. */
|
/* Store the agent address as a string. */
|
||||||
if (x->agentAddr.type == SFLOW_ADDRTYPE_IP6) {
|
if (x->agentAddr.type == SFLOW_ADDRTYPE_IP6) {
|
||||||
snprintf(x->agentIPStr, SFLOW_MAX_AGENTIP_STRLEN,
|
char ipstr[INET6_ADDRSTRLEN];
|
||||||
"%04x:%04x:%04x:%04x",
|
inet_ntop(AF_INET6, (const void *) &x->agentAddr.a.ip6,
|
||||||
x->agentAddr.a.ip6[0],
|
ipstr, INET6_ADDRSTRLEN);
|
||||||
x->agentAddr.a.ip6[1],
|
snprintf(x->agentIPStr, sizeof x->agentIPStr, "[%s]", ipstr);
|
||||||
x->agentAddr.a.ip6[2],
|
|
||||||
x->agentAddr.a.ip6[3]);
|
|
||||||
} else {
|
} else {
|
||||||
snprintf(x->agentIPStr, SFLOW_MAX_AGENTIP_STRLEN,
|
snprintf(x->agentIPStr, sizeof x->agentIPStr,
|
||||||
IP_FMT, IP_ARGS(x->agentAddr.a.ip4));
|
IP_FMT, IP_ARGS(x->agentAddr.a.ip4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -466,12 +466,12 @@ collect_in_band_managers(const struct ovsrec_open_vswitch *ovs_cfg,
|
|||||||
|
|
||||||
managers = xmalloc(sset_count(&targets) * sizeof *managers);
|
managers = xmalloc(sset_count(&targets) * sizeof *managers);
|
||||||
SSET_FOR_EACH (target, &targets) {
|
SSET_FOR_EACH (target, &targets) {
|
||||||
struct sockaddr_in *sin = &managers[n_managers];
|
struct sockaddr_storage ss;
|
||||||
|
|
||||||
if (stream_parse_target_with_default_port(target,
|
if (stream_parse_target_with_default_port(target, OVSDB_OLD_PORT,
|
||||||
OVSDB_OLD_PORT,
|
&ss)
|
||||||
sin)) {
|
&& ss.ss_family == AF_INET) {
|
||||||
n_managers++;
|
managers[n_managers++] = *(struct sockaddr_in *) &ss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3000,12 +3000,18 @@
|
|||||||
</dd>
|
</dd>
|
||||||
<dt><code>tcp:<var>ip</var></code>[<code>:<var>port</var></code>]</dt>
|
<dt><code>tcp:<var>ip</var></code>[<code>:<var>port</var></code>]</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>The specified TCP <var>port</var> on the host at the
|
<p>
|
||||||
given <var>ip</var>, which must be expressed as an IP
|
The specified TCP <var>port</var> on the host at the given
|
||||||
address (not a DNS name).</p>
|
<var>ip</var>, which must be expressed as an IP address (not a
|
||||||
<p>If <var>port</var> is not specified, it currently
|
DNS name), where <var>ip</var> can be IPv4 or IPv6 address. If
|
||||||
defaults to 6633. In the future, the default will change to
|
<var>ip</var> is an IPv6 address, wrap it in square brackets,
|
||||||
6653, which is the IANA-defined value.</p>
|
e.g. <code>tcp:[::1]:6632</code>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If <var>port</var> is not specified, it currently defaults to
|
||||||
|
6633. In the future, the default will change to 6653, which is
|
||||||
|
the IANA-defined value.
|
||||||
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<p>
|
<p>
|
||||||
@@ -3015,29 +3021,48 @@
|
|||||||
<dl>
|
<dl>
|
||||||
<dt><code>pssl:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
<dt><code>pssl:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p> Listens for SSL connections on the specified TCP
|
<p>
|
||||||
<var>port</var>. If <var>ip</var>, which must be expressed
|
Listens for SSL connections on the specified TCP <var>port</var>.
|
||||||
as an IP address (not a DNS name), is specified, then
|
If <var>ip</var>, which must be expressed as an IP address (not a
|
||||||
connections are restricted to the specified local IP
|
DNS name), is specified, then connections are restricted to the
|
||||||
address. The <ref table="Open_vSwitch" column="ssl"/>
|
specified local IP address (either IPv4 or IPv6). If
|
||||||
column in the <ref table="Open_vSwitch"/> table must point
|
<var>ip</var> is an IPv6 address, wrap it in square brackets,
|
||||||
to a valid SSL configuration when this form is used.</p>
|
e.g. <code>pssl:6632:[::1]</code>.
|
||||||
<p>If <var>port</var> is not specified, it currently
|
</p>
|
||||||
defaults to 6633. In the future, the default will change to
|
<p>
|
||||||
6653, which is the IANA-defined value.</p>
|
If <var>port</var> is not specified, it currently defaults to
|
||||||
<p>SSL support is an optional feature that is not always built as
|
6633. If <var>ip</var> is not specified then it listens only on
|
||||||
part of Open vSwitch.</p>
|
IPv4 (but not IPv6) addresses. The
|
||||||
|
<ref table="Open_vSwitch" column="ssl"/>
|
||||||
|
column in the <ref table="Open_vSwitch"/> table must point to a
|
||||||
|
valid SSL configuration when this form is used.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If <var>port</var> is not specified, it currently defaults to
|
||||||
|
6633. In the future, the default will change to 6653, which is
|
||||||
|
the IANA-defined value.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
SSL support is an optional feature that is not always built as
|
||||||
|
part of Open vSwitch.
|
||||||
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>ptcp:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
<dt><code>ptcp:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>Listens for connections on the specified TCP
|
<p>
|
||||||
<var>port</var>. If <var>ip</var>, which must be expressed
|
Listens for connections on the specified TCP <var>port</var>. If
|
||||||
as an IP address (not a DNS name), is specified, then
|
<var>ip</var>, which must be expressed as an IP address (not a
|
||||||
connections are restricted to the specified local IP
|
DNS name), is specified, then connections are restricted to the
|
||||||
address.</p>
|
specified local IP address (either IPv4 or IPv6). If
|
||||||
<p>If <var>port</var> is not specified, it currently
|
<var>ip</var> is an IPv6 address, wrap it in square brackets,
|
||||||
defaults to 6633. In the future, the default will change to
|
e.g. <code>ptcp:6632:[::1]</code>. If <var>ip</var> is not
|
||||||
6653, which is the IANA-defined value.</p>
|
specified then it listens only on IPv4 addresses.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If <var>port</var> is not specified, it currently defaults to
|
||||||
|
6633. In the future, the default will change to 6653, which is
|
||||||
|
the IANA-defined value.
|
||||||
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<p>When multiple controllers are configured for a single bridge, the
|
<p>When multiple controllers are configured for a single bridge, the
|
||||||
@@ -3331,8 +3356,10 @@
|
|||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
The specified TCP <var>port</var> on the host at the given
|
The specified TCP <var>port</var> on the host at the given
|
||||||
<var>ip</var>, which must be expressed as an IP address
|
<var>ip</var>, which must be expressed as an IP address (not a
|
||||||
(not a DNS name).
|
DNS name), where <var>ip</var> can be IPv4 or IPv6 address. If
|
||||||
|
<var>ip</var> is an IPv6 address, wrap it in square brackets,
|
||||||
|
e.g. <code>tcp:[::1]:6632</code>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If <var>port</var> is not specified, it currently defaults
|
If <var>port</var> is not specified, it currently defaults
|
||||||
@@ -3343,13 +3370,16 @@
|
|||||||
<dt><code>pssl:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
<dt><code>pssl:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Listens for SSL connections on the specified TCP
|
Listens for SSL connections on the specified TCP <var>port</var>.
|
||||||
<var>port</var>. Specify 0 for <var>port</var> to have
|
Specify 0 for <var>port</var> to have the kernel automatically
|
||||||
the kernel automatically choose an available port. If
|
choose an available port. If <var>ip</var>, which must be
|
||||||
<var>ip</var>, which must be expressed as an IP address
|
expressed as an IP address (not a DNS name), is specified, then
|
||||||
(not a DNS name), is specified, then connections are
|
connections are restricted to the specified local IP address
|
||||||
restricted to the specified local IP address. The <ref
|
(either IPv4 or IPv6 address). If <var>ip</var> is an IPv6
|
||||||
table="Open_vSwitch" column="ssl"/> column in the <ref
|
address, wrap in square brackets,
|
||||||
|
e.g. <code>pssl:6632:[::1]</code>. If <var>ip</var> is not
|
||||||
|
specified then it listens only on IPv4 (but not IPv6) addresses.
|
||||||
|
The <ref table="Open_vSwitch" column="ssl"/> column in the <ref
|
||||||
table="Open_vSwitch"/> table must point to a valid SSL
|
table="Open_vSwitch"/> table must point to a valid SSL
|
||||||
configuration when this form is used.
|
configuration when this form is used.
|
||||||
</p>
|
</p>
|
||||||
@@ -3366,12 +3396,15 @@
|
|||||||
<dt><code>ptcp:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
<dt><code>ptcp:</code>[<var>port</var>][<code>:<var>ip</var></code>]</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Listens for connections on the specified TCP
|
Listens for connections on the specified TCP <var>port</var>.
|
||||||
<var>port</var>. Specify 0 for <var>port</var> to have
|
Specify 0 for <var>port</var> to have the kernel automatically
|
||||||
the kernel automatically choose an available port. If
|
choose an available port. If <var>ip</var>, which must be
|
||||||
<var>ip</var>, which must be expressed as an IP address
|
expressed as an IP address (not a DNS name), is specified, then
|
||||||
(not a DNS name), is specified, then connections are
|
connections are restricted to the specified local IP address
|
||||||
restricted to the specified local IP address.
|
(either IPv4 or IPv6 address). If <var>ip</var> is an IPv6
|
||||||
|
address, wrap it in square brackets,
|
||||||
|
e.g. <code>ptcp:6632:[::1]</code>. If <var>ip</var> is not
|
||||||
|
specified then it listens only on IPv4 addresses.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If <var>port</var> is not specified, it currently defaults
|
If <var>port</var> is not specified, it currently defaults
|
||||||
|
Reference in New Issue
Block a user