forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support vlan_group workaround implemented in XenServer kernels.
Some Linux network drivers support a feature called "VLAN acceleration", associated with a data structure called a "vlan_group". A vlan_group is, abstractly, a dictionary that maps from a VLAN ID (in the range 0...4095) to a VLAN device, that is, a Linux network device associated with a particular VLAN, e.g. "eth0.9" for VLAN 9 on eth0. Some drivers that support VLAN acceleration have bugs that fall roughly into the following categories: * Some NICs strip VLAN tags on receive if no vlan_group is registered, so that the tag is completely lost. * Some drivers size their receive buffers based on whether a vlan_group is enabled, meaning that a maximum size packet with a VLAN tag will not fit if a vlan_group is not configured. * On transmit some drivers expect that VLAN acceleration will be used if it is available (which can only be done if a vlan_group is configured). In these cases, the driver may fail to parse the packet and correctly setup checksum offloading and/or TSO. The correct long term solution is to fix these driver bugs. To cope until then, we have prepared a patch to the Linux kernel network stack that works around these problems. This commit adds support for the workaround implemented by that patch. Signed-off-by: Ben Pfaff <[email protected]> Acked-by: Jesse Gross <[email protected]>
- Loading branch information
Showing
11 changed files
with
345 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
.\" -*- nroff -*- | ||
.de IQ | ||
. br | ||
. ns | ||
. IP "\\$1" | ||
.. | ||
.TH ovs\-vlan\-bug\-workaround 8 "February 2011" "Open vSwitch" "Open vSwitch Manual" | ||
.ds PN ovs\-vlan\-bug\-workaround | ||
. | ||
.SH NAME | ||
ovs\-vlan\-bug\-workaround \- utility for configuring Linux VLAN driver bug workaround | ||
. | ||
.SH SYNOPSIS | ||
\fBovs\-vlan\-bug\-workaround \fInetdev\fR \fBon\fR | ||
.br | ||
\fBovs\-vlan\-bug\-workaround \fInetdev\fR \fBoff\fR | ||
.br | ||
\fBovs\-vlan\-bug\-workaround \-\-help | ||
.br | ||
\fBovs\-vlan\-bug\-workaround \-\-version | ||
.SH DESCRIPTION | ||
. | ||
.PP | ||
Some Linux network drivers support a feature called ``VLAN | ||
acceleration''. VLAN acceleration is associated with a data structure | ||
called a \fBvlan_group\fR that is, abstractly, a dictionary that maps | ||
from a VLAN ID (in the range 0 to 4095) to a VLAN device, that is, a | ||
Linux network device associated with a particular VLAN, | ||
e.g. \fBeth0.9\fR for VLAN 9 on \fBeth0\fR. | ||
.PP | ||
Some drivers that support VLAN acceleration have bugs that fall | ||
roughly into the categories listed below. \fBovs\-vlan\-test\fR(8) | ||
can test for these driver bugs. | ||
.so utilities/ovs-vlan-bugs.man | ||
.PP | ||
.PP | ||
The correct long term solution is to fix these driver bugs. | ||
.PP | ||
For now, \fBovs\-vlan\-bug\-workaround\fR can enable a special-purpose | ||
workaround for devices with buggy VLAN acceleration. A kernel patch | ||
must be applied for this workaround to work. | ||
.PP | ||
Use the command \fBovs\-vlan\-bug\-workaround \fInetdev\fR \fBon\fR to | ||
enable the VLAN driver bug workaround for network device \fInetdev\fR. | ||
Use the command \fBovs\-vlan\-bug\-workaround \fInetdev\fR \fBoff\fR to | ||
disable the VLAN driver bug workaround for network device \fInetdev\fR. | ||
.SH "DRIVER DETAILS" | ||
.PP | ||
The following drivers in Linux version | ||
2.6.32.12-0.7.1.xs1.0.0.311.170586 implement VLAN acceleration and are | ||
relevant to Open vSwitch on XenServer. We have not tested any version | ||
of most of these drivers, so we do not know whether they have a VLAN | ||
problem that needs to be fixed. The drivers are listed by the name | ||
that they report in, e.g., \fBethtool \-i\fR output; in a few cases | ||
this differs slightly from the name of the module's \fB.ko\fR file: | ||
. | ||
.nf | ||
.ta T 1i | ||
\fB8139cp acenic amd8111e atl1c ATL1E atl1 | ||
atl2 be2net bna bnx2 bnx2x cnic | ||
cxgb cxgb3 e1000 e1000e enic forcedeth | ||
igb igbvf ixgb ixgbe jme ml4x_core | ||
ns83820 qlge r8169 S2IO sky2 starfire | ||
tehuti tg3 typhoon via-velocity vxge | ||
.fi | ||
.PP | ||
The following drivers use \fBvlan_group\fR but are irrelevant to Open | ||
vSwitch on XenServer: | ||
.IP "\fBbonding\fR" | ||
Not used with Open vSwitch on XenServer. | ||
.IP "\fBgianfar\fR" | ||
Not shipped with XenServer. A FreeScale CPU-integrated device. | ||
.IP "\fBehea\fR" | ||
Cannot be built on x86. IBM Power architecture only. | ||
.IP "\fBstmmac\fR" | ||
Cannot be built on x86. SH4 architecture only. | ||
.IP "\fBvmxnet3\fR" | ||
Not shipped with XenServer. For use inside VMware VMs only. | ||
. | ||
.SH OPTIONS | ||
. | ||
.so lib/common.man | ||
. | ||
.SH BUGS | ||
. | ||
Obviously. | ||
. | ||
.SH "SEE ALSO" | ||
. | ||
.BR ovs\-vlan\-test (8). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright (c) 2011 Nicira Networks. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <config.h> | ||
|
||
#include <errno.h> | ||
#include <getopt.h> | ||
#include <linux/if_vlan.h> | ||
#include <linux/sockios.h> | ||
#include <net/if.h> | ||
#include <stdlib.h> | ||
#include <sys/ioctl.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "command-line.h" | ||
#include "util.h" | ||
|
||
#define ADD_ALL_VLANS_CMD 10 | ||
#define DEL_ALL_VLANS_CMD 11 | ||
|
||
static void usage(void); | ||
static void parse_options(int argc, char *argv[]); | ||
|
||
int | ||
main(int argc, char *argv[]) | ||
{ | ||
struct vlan_ioctl_args vlan_args; | ||
const char *netdev, *setting; | ||
int fd; | ||
|
||
set_program_name(argv[0]); | ||
|
||
parse_options(argc, argv); | ||
if (argc - optind != 2) { | ||
ovs_fatal(0, "exactly two non-option arguments are required " | ||
"(use --help for help)"); | ||
} | ||
|
||
memset(&vlan_args, 0, sizeof vlan_args); | ||
|
||
/* Get command. */ | ||
setting = argv[optind + 1]; | ||
if (!strcmp(setting, "on")) { | ||
vlan_args.cmd = ADD_ALL_VLANS_CMD; | ||
} else if (!strcmp(setting, "off")) { | ||
vlan_args.cmd = DEL_ALL_VLANS_CMD; | ||
} else { | ||
ovs_fatal(0, "second command line argument must be \"on\" or \"off\" " | ||
"(not \"%s\")", setting); | ||
} | ||
|
||
/* Get network device name. */ | ||
netdev = argv[optind]; | ||
if (strlen(netdev) >= IFNAMSIZ) { | ||
ovs_fatal(0, "%s: network device name too long", netdev); | ||
} | ||
strcpy(vlan_args.device1, netdev); | ||
|
||
/* Execute operation. */ | ||
fd = socket(AF_INET, SOCK_STREAM, 0); | ||
if (fd < 0) { | ||
ovs_fatal(errno, "socket creation failed"); | ||
} | ||
if (ioctl(fd, SIOCSIFVLAN, &vlan_args) < 0) { | ||
if (errno == ENOPKG) { | ||
ovs_fatal(0, "operation failed (8021q module not loaded)"); | ||
} else if (errno == EOPNOTSUPP) { | ||
ovs_fatal(0, "operation failed (kernel does not support the " | ||
"VLAN bug workaround)"); | ||
} else { | ||
ovs_fatal(errno, "operation failed"); | ||
} | ||
} | ||
close(fd); | ||
|
||
return 0; | ||
} | ||
|
||
static void | ||
usage(void) | ||
{ | ||
printf("\ | ||
%s, for enabling or disabling the kernel VLAN bug workaround\n\ | ||
usage: %s NETDEV SETTING\n\ | ||
where NETDEV is a network device (e.g. \"eth0\")\n\ | ||
and SETTING is \"on\" to enable the workaround or \"off\" to disable it.\n\ | ||
\n\ | ||
Options:\n\ | ||
-h, --help Print this helpful information\n\ | ||
-V, --version Display version information\n", | ||
program_name, program_name); | ||
exit(EXIT_SUCCESS); | ||
} | ||
|
||
static void | ||
parse_options(int argc, char *argv[]) | ||
{ | ||
static const struct option long_options[] = { | ||
{"help", no_argument, NULL, 'h'}, | ||
{"version", no_argument, NULL, 'V'}, | ||
{0, 0, 0, 0}, | ||
}; | ||
char *short_options = long_options_to_short_options(long_options); | ||
|
||
for (;;) { | ||
int option; | ||
|
||
option = getopt_long(argc, argv, "+t:hVe", long_options, NULL); | ||
if (option == -1) { | ||
break; | ||
} | ||
switch (option) { | ||
case 'h': | ||
usage(); | ||
break; | ||
|
||
case 'V': | ||
OVS_PRINT_VERSION(0, 0); | ||
exit(EXIT_SUCCESS); | ||
|
||
case '?': | ||
exit(EXIT_FAILURE); | ||
|
||
default: | ||
NOT_REACHED(); | ||
} | ||
} | ||
free(short_options); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.IP \(bu | ||
When NICs use VLAN stripping on receive they must pass a pointer to a | ||
\fBvlan_group\fR when reporting the stripped tag to the networking | ||
core. If no \fBvlan_group\fR is in use then some drivers just drop | ||
the extracted tag. Drivers are supposed to only enable stripping if a | ||
\fBvlan_group\fR is registered but not all of them do that. | ||
. | ||
.IP \(bu | ||
Some drivers size their receive buffers based on whether a | ||
\fBvlan_group\fR is enabled, meaning that a maximum size packet with a | ||
VLAN tag will not fit if no \fBvlan_group\fR is configured. | ||
. | ||
.IP \(bu | ||
On transmit, some drivers expect that VLAN acceleration will be used | ||
if it is available, which can only be done if a \fBvlan_group\fR is | ||
configured. In these cases, the driver may fail to parse the packet | ||
and correctly setup checksum offloading or TSO. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.