Currently the TTL is copied from the inner packet of the tunnel to
the outer packet if the inner packet is IP. This is good if your
GRE packets might make it into the input of your device but bad
if you want to be fully transparent.
This also resolves an inconsistency between tunnels set up using
the ioctl and using Netlink. The ioctl version would force PMTUD
on if a fixed TTL is set as a backup way to prevent loops but it
never made it over to the newer Netlink code so obviously no one
cares too much about it. This removes it to provide consistency
and transparency.
Basically, don't create loops and you will be happy.
If we are using netlink to get stats and get_ifindex() fails, then for
an internal network device we will then swap around a bunch of
indeterminate (uninitialized) data values. That won't hurt anything--the
caller will still set them to all-1-bits due to the error--but it still
seems wrong. So this commit avoid it.
Found using Clang (http://clang-analyzer.llvm.org/).
We previously maintained a list of open devices inside of the
linux netdev. Since the netdev library now maintains this list,
it is better to use that list instead of our own.
Never close the file descriptor if it is 0, since it is never a
valid FD in this context. Also initialize the FD to -1 so that
it is never set to a valid but incorrect value.
We were storing a struct netdev_dev_linux ** instead of a
netdev_dev_linux * in the cache map. This prevented the cache
from being invalidated on changes such as link status.
The default burst rate was 10Kb. This increases it to 1000kb, since
we were having problems getting traffic through at 10kb. A better value
probably exists between these two points, but that will require
additional experimentation.
Calling close(0) at random points is bad. It means that the next call to
socket() or open() returns fd 0. Then the next time a netdev gets closed,
that socket or file fd gets closed too, and you end up with weird "Bad
file descriptor" errors.
Found by installing the following as lib/unistd.h in the source tree:
#ifndef UNISTD_H
#define UNISTD_H 1
#include <stdlib.h>
#include_next <unistd.h>
#undef close
#define close(fd) rpl_close(fd)
static inline int rpl_close(int fd)
{
if (!fd) {
abort();
}
return (close)(fd);
}
#endif
TAP devices need to be treated slightly differently from other other
devices because they cannot be opened multiple times. Instead we
open them once and share the file descriptor. This means that if
the netdev is opened multiple times one reader can drain the buffers
of another. While this is a deviation from the normal convention,
it does not impact current or planned users.
In addition, this cleans up some confusion between the file
descriptor for tap devices versus other FD's.
This builds on earlier work that implemented netdev object refcounting.
However, rather than requiring explicit create and destroy calls,
these operations are now performed automatically based on the referenece
count. This is important because in certain situations it is not
possible to know whether a netdev has already been created. A
workaround existed (which looked fairly similar to this paradigm) but
introduced it's own issues. This simplifies and unifies the API.
The latest version of GCC flags a common socket convention as breaking
strict-aliasing rules. This commit removes the aliasing and gets rid of
the scary warning.
This implements the userspace portion of GRE on Linux. It communicates
with the kernel module to setup tunnels using either Netlink or ioctls
as appropriate based on the kernel version.
Significant portions of this commit were actually written by
Justin Pettit.
This change adds netdev_create() and netdev_destroy() functions to allow
the creation of network devices through the netdev library. Previously,
network devices had to already exist or be created on demand through
netdev_open(). This caused problems such as not being able to specify
TAP devices as ports in ovs-vswitchd, which this patch fixes.
This also lays the groundwork for adding GRE and VDE support.
The comment on netdev_get_features() claimed that all of the passed-in
values were set to 0 on failure, but the implementation didn't live up
to the promise.
CC: Paul Ingram <paul@nicira.com>
Fixes a bug whereby netdev_linux_set_etheraddr() would update the cached
Ethernet address but not mark it valid. (This potentially wasted a system
call later but wasn't harmful.)
As an added optimization, don't set the Ethernet address at all if the
new address is the same as the current address.
netdev_linux_receive was returning positive error codes while the
interface specifies that it should be returning negative errors.
This difference causes a huge increase in (non-existant) packet
processing with the userspace datapath.
Whether a port is internal is cached to avoid requerying the kernel
every time stats are requested. However, the cache vality bit was
never being set so the cache wasn't used. This corrects that
oversight.
Thanks to Ben Pfaff for noticing.
Internal ports appear to have their transmit and receive stats swapped
because from the kernel's point of view these ports are acting like
the machine connected to the switch, not the switch itself. This swaps
the stats for consistency with other ports.
It was getting to be too confusing to have both netdev_linux_* functions
and linux_netdev_* functions. Rename the latter to make the distinction
more obvious. "rtnetlink" seems to be a fairly good name because that's
what the kernel calls it, so the name will be familiar at least to people
who know about rtnetlink.
This new abstraction layer allows multiple implementations of network
devices in a single running process. This will be useful, for example, to
support network devices that are simulated entirely in the running process
or that communicate with other processes over Unix domain sockets, etc.
The reimplemented tap device support in this commit has not been tested.
The dpif and netdev code has had various ways to check for changes to
dpifs and netdevs over the course of Open vSwitch development. All of
these have been thus far fairly specific to the Linux implementation. This
commit is the start of a more general API for watching for such changes.
The dpif-related parts seem fairly mature and so they are documented,
the netdev parts will probably need to change somewhat and so they are
not documented yet.