2005-01-07 01:45:51 +00:00
|
|
|
/*-
|
1994-05-24 10:09:53 +00:00
|
|
|
* Copyright (c) 1982, 1986, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
2001-10-17 10:44:39 +00:00
|
|
|
* @(#)if_loop.c 8.2 (Berkeley) 1/9/95
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Loopback interface driver for protocol testing and timing.
|
|
|
|
*/
|
|
|
|
|
1998-01-08 23:42:31 +00:00
|
|
|
#include "opt_inet.h"
|
1999-12-07 17:39:16 +00:00
|
|
|
#include "opt_inet6.h"
|
1997-12-15 20:31:25 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/mbuf.h>
|
2001-01-31 07:58:58 +00:00
|
|
|
#include <sys/module.h>
|
2002-03-04 21:46:00 +00:00
|
|
|
#include <machine/bus.h>
|
|
|
|
#include <sys/rman.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/socket.h>
|
1997-03-24 11:33:46 +00:00
|
|
|
#include <sys/sockio.h>
|
2001-01-29 11:06:26 +00:00
|
|
|
#include <sys/sysctl.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
|
|
|
|
#include <net/if.h>
|
2013-10-26 17:58:36 +00:00
|
|
|
#include <net/if_var.h>
|
Major overhaul of pseudo-interface cloning. Highlights include:
- Split the code out into if_clone.[ch].
- Locked struct if_clone. [1]
- Add a per-cloner match function rather then simply matching names of
the form <name><unit> and <name>.
- Use the match function to allow creation of <interface>.<tag>
vlan interfaces. The old way is preserved unchanged!
- Also the match function to allow creation of stf(4) interfaces named
stf0, stf, or 6to4. This is the only major user visible change in
that "ifconfig stf" creates the interface stf rather then stf0 and
does not print "stf0" to stdout.
- Allow destroy functions to fail so they can refuse to delete
interfaces. Currently, we forbid the deletion of interfaces which
were created in the init function, particularly lo0, pflog0, and
pfsync0. In the case of lo0 this was a panic implementation so it
does not count as a user visiable change. :-)
- Since most interfaces do not need the new functionality, an family of
wrapper functions, ifc_simple_*(), were created to wrap old style
cloner functions.
- The IF_CLONE_INITIALIZER macro is replaced with a new incompatible
IFC_CLONE_INITIALIZER and ifc_simple consumers use IFC_SIMPLE_DECLARE
instead.
Submitted by: Maurycy Pawlowski-Wieronski <maurycy at fouk.org> [1]
Reviewed by: andre, mlaier
Discussed on: net
2004-06-22 20:13:25 +00:00
|
|
|
#include <net/if_clone.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <net/if_types.h>
|
|
|
|
#include <net/netisr.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
#include <net/bpf.h>
|
2008-12-02 21:37:28 +00:00
|
|
|
#include <net/vnet.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
|
|
|
|
#ifdef INET
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_var.h>
|
|
|
|
#endif
|
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
#ifdef INET6
|
|
|
|
#ifndef INET
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
#include <netinet6/in6_var.h>
|
2000-07-04 16:35:15 +00:00
|
|
|
#include <netinet/ip6.h>
|
1999-11-22 02:45:11 +00:00
|
|
|
#endif
|
|
|
|
|
2009-01-10 23:50:23 +00:00
|
|
|
#include <security/mac/mac_framework.h>
|
|
|
|
|
1994-05-29 07:43:54 +00:00
|
|
|
#ifdef TINY_LOMTU
|
1994-05-24 10:09:53 +00:00
|
|
|
#define LOMTU (1024+512)
|
1999-11-22 02:45:11 +00:00
|
|
|
#elif defined(LARGE_LOMTU)
|
|
|
|
#define LOMTU 131072
|
1994-05-29 07:43:54 +00:00
|
|
|
#else
|
1995-03-04 04:28:50 +00:00
|
|
|
#define LOMTU 16384
|
1994-05-29 07:43:54 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2009-03-16 10:56:50 +00:00
|
|
|
#define LO_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP)
|
2012-05-30 20:56:07 +00:00
|
|
|
#define LO_CSUM_FEATURES6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_SCTP_IPV6)
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
#define LO_CSUM_SET (CSUM_DATA_VALID | CSUM_DATA_VALID_IPV6 | \
|
|
|
|
CSUM_PSEUDO_HDR | \
|
2009-03-16 10:56:50 +00:00
|
|
|
CSUM_IP_CHECKED | CSUM_IP_VALID | \
|
|
|
|
CSUM_SCTP_VALID)
|
|
|
|
|
2002-03-04 21:46:00 +00:00
|
|
|
int loioctl(struct ifnet *, u_long, caddr_t);
|
|
|
|
int looutput(struct ifnet *ifp, struct mbuf *m,
|
2013-04-26 12:50:32 +00:00
|
|
|
const struct sockaddr *dst, struct route *ro);
|
2006-07-09 06:04:01 +00:00
|
|
|
static int lo_clone_create(struct if_clone *, int, caddr_t);
|
2004-04-14 00:57:49 +00:00
|
|
|
static void lo_clone_destroy(struct ifnet *);
|
2002-03-04 21:46:00 +00:00
|
|
|
|
Build on Jeff Roberson's linker-set based dynamic per-CPU allocator
(DPCPU), as suggested by Peter Wemm, and implement a new per-virtual
network stack memory allocator. Modify vnet to use the allocator
instead of monolithic global container structures (vinet, ...). This
change solves many binary compatibility problems associated with
VIMAGE, and restores ELF symbols for virtualized global variables.
Each virtualized global variable exists as a "reference copy", and also
once per virtual network stack. Virtualized global variables are
tagged at compile-time, placing the in a special linker set, which is
loaded into a contiguous region of kernel memory. Virtualized global
variables in the base kernel are linked as normal, but those in modules
are copied and relocated to a reserved portion of the kernel's vnet
region with the help of a the kernel linker.
Virtualized global variables exist in per-vnet memory set up when the
network stack instance is created, and are initialized statically from
the reference copy. Run-time access occurs via an accessor macro, which
converts from the current vnet and requested symbol to a per-vnet
address. When "options VIMAGE" is not compiled into the kernel, normal
global ELF symbols will be used instead and indirection is avoided.
This change restores static initialization for network stack global
variables, restores support for non-global symbols and types, eliminates
the need for many subsystem constructors, eliminates large per-subsystem
structures that caused many binary compatibility issues both for
monitoring applications (netstat) and kernel modules, removes the
per-function INIT_VNET_*() macros throughout the stack, eliminates the
need for vnet_symmap ksym(2) munging, and eliminates duplicate
definitions of virtualized globals under VIMAGE_GLOBALS.
Bump __FreeBSD_version and update UPDATING.
Portions submitted by: bz
Reviewed by: bz, zec
Discussed with: gnn, jamie, jeff, jhb, julian, sam
Suggested by: peter
Approved by: re (kensmith)
2009-07-14 22:48:30 +00:00
|
|
|
VNET_DEFINE(struct ifnet *, loif); /* Used externally */
|
2002-03-04 21:46:00 +00:00
|
|
|
|
2009-05-23 21:43:44 +00:00
|
|
|
#ifdef VIMAGE
|
2012-10-16 13:37:54 +00:00
|
|
|
static VNET_DEFINE(struct if_clone *, lo_cloner);
|
2009-07-16 21:13:04 +00:00
|
|
|
#define V_lo_cloner VNET(lo_cloner)
|
Build on Jeff Roberson's linker-set based dynamic per-CPU allocator
(DPCPU), as suggested by Peter Wemm, and implement a new per-virtual
network stack memory allocator. Modify vnet to use the allocator
instead of monolithic global container structures (vinet, ...). This
change solves many binary compatibility problems associated with
VIMAGE, and restores ELF symbols for virtualized global variables.
Each virtualized global variable exists as a "reference copy", and also
once per virtual network stack. Virtualized global variables are
tagged at compile-time, placing the in a special linker set, which is
loaded into a contiguous region of kernel memory. Virtualized global
variables in the base kernel are linked as normal, but those in modules
are copied and relocated to a reserved portion of the kernel's vnet
region with the help of a the kernel linker.
Virtualized global variables exist in per-vnet memory set up when the
network stack instance is created, and are initialized statically from
the reference copy. Run-time access occurs via an accessor macro, which
converts from the current vnet and requested symbol to a per-vnet
address. When "options VIMAGE" is not compiled into the kernel, normal
global ELF symbols will be used instead and indirection is avoided.
This change restores static initialization for network stack global
variables, restores support for non-global symbols and types, eliminates
the need for many subsystem constructors, eliminates large per-subsystem
structures that caused many binary compatibility issues both for
monitoring applications (netstat) and kernel modules, removes the
per-function INIT_VNET_*() macros throughout the stack, eliminates the
need for vnet_symmap ksym(2) munging, and eliminates duplicate
definitions of virtualized globals under VIMAGE_GLOBALS.
Bump __FreeBSD_version and update UPDATING.
Portions submitted by: bz
Reviewed by: bz, zec
Discussed with: gnn, jamie, jeff, jhb, julian, sam
Suggested by: peter
Approved by: re (kensmith)
2009-07-14 22:48:30 +00:00
|
|
|
#endif
|
Introduce vnet module registration / initialization framework with
dependency tracking and ordering enforcement.
With this change, per-vnet initialization functions introduced with
r190787 are no longer directly called from traditional initialization
functions (which cc in most cases inlined to pre-r190787 code), but are
instead registered via the vnet framework first, and are invoked only
after all prerequisite modules have been initialized. In the long run,
this framework should allow us to both initialize and dismantle
multiple vnet instances in a correct order.
The problem this change aims to solve is how to replay the
initialization sequence of various network stack components, which
have been traditionally triggered via different mechanisms (SYSINIT,
protosw). Note that this initialization sequence was and still can be
subtly different depending on whether certain pieces of code have been
statically compiled into the kernel, loaded as modules by boot
loader, or kldloaded at run time.
The approach is simple - we record the initialization sequence
established by the traditional mechanisms whenever vnet_mod_register()
is called for a particular vnet module. The vnet_mod_register_multi()
variant allows a single initializer function to be registered multiple
times but with different arguments - currently this is only used in
kern/uipc_domain.c by net_add_domain() with different struct domain *
as arguments, which allows for protosw-registered initialization
routines to be invoked in a correct order by the new vnet
initialization framework.
For the purpose of identifying vnet modules, each vnet module has to
have a unique ID, which is statically assigned in sys/vimage.h.
Dynamic assignment of vnet module IDs is not supported yet.
A vnet module may specify a single prerequisite module at registration
time by filling in the vmi_dependson field of its vnet_modinfo struct
with the ID of the module it depends on. Unless specified otherwise,
all vnet modules depend on VNET_MOD_NET (container for ifnet list head,
rt_tables etc.), which thus has to and will always be initialized
first. The framework will panic if it detects any unresolved
dependencies before completing system initialization. Detection of
unresolved dependencies for vnet modules registered after boot
(kldloaded modules) is not provided.
Note that the fact that each module can specify only a single
prerequisite may become problematic in the long run. In particular,
INET6 depends on INET being already instantiated, due to TCP / UDP
structures residing in INET container. IPSEC also depends on INET,
which will in turn additionally complicate making INET6-only kernel
configs a reality.
The entire registration framework can be compiled out by turning on the
VIMAGE_GLOBALS kernel config option.
Reviewed by: bz
Approved by: julian (mentor)
2009-04-11 05:58:58 +00:00
|
|
|
|
2012-10-16 13:37:54 +00:00
|
|
|
static struct if_clone *lo_cloner;
|
|
|
|
static const char loname[] = "lo";
|
2002-03-04 21:46:00 +00:00
|
|
|
|
2004-04-14 00:57:49 +00:00
|
|
|
static void
|
2008-04-07 01:43:30 +00:00
|
|
|
lo_clone_destroy(struct ifnet *ifp)
|
2002-03-04 21:46:00 +00:00
|
|
|
{
|
|
|
|
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
#ifndef VIMAGE
|
2002-05-25 20:17:04 +00:00
|
|
|
/* XXX: destroying lo0 will lead to panics. */
|
Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).
This is the first in a series of commits over the course
of the next few weeks.
Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.
We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.
Obtained from: //depot/projects/vimage-commit2/...
Reviewed by: brooks, des, ed, mav, julian,
jamie, kris, rwatson, zec, ...
(various people I forgot, different versions)
md5 (with a bit of help)
Sponsored by: NLnet Foundation, The FreeBSD Foundation
X-MFC after: never
V_Commit_Message_Reviewed_By: more people than the patch
2008-08-17 23:27:27 +00:00
|
|
|
KASSERT(V_loif != ifp, ("%s: destroying lo0", __func__));
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
#endif
|
2002-03-04 21:46:00 +00:00
|
|
|
|
|
|
|
bpfdetach(ifp);
|
|
|
|
if_detach(ifp);
|
2005-06-10 16:49:24 +00:00
|
|
|
if_free(ifp);
|
2002-03-04 21:46:00 +00:00
|
|
|
}
|
|
|
|
|
2004-04-14 00:57:49 +00:00
|
|
|
static int
|
2008-04-07 01:43:30 +00:00
|
|
|
lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
2001-01-29 11:06:26 +00:00
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp;
|
2001-01-29 11:06:26 +00:00
|
|
|
|
2008-06-29 13:17:01 +00:00
|
|
|
ifp = if_alloc(IFT_LOOP);
|
|
|
|
if (ifp == NULL)
|
2005-06-10 16:49:24 +00:00
|
|
|
return (ENOSPC);
|
|
|
|
|
2012-10-16 13:37:54 +00:00
|
|
|
if_initname(ifp, loname, unit);
|
2005-06-10 16:49:24 +00:00
|
|
|
ifp->if_mtu = LOMTU;
|
|
|
|
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
|
|
|
|
ifp->if_ioctl = loioctl;
|
|
|
|
ifp->if_output = looutput;
|
|
|
|
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
ifp->if_capabilities = ifp->if_capenable =
|
|
|
|
IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6;
|
|
|
|
ifp->if_hwassist = LO_CSUM_FEATURES | LO_CSUM_FEATURES6;
|
2005-06-10 16:49:24 +00:00
|
|
|
if_attach(ifp);
|
2005-06-26 18:11:11 +00:00
|
|
|
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
|
Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).
This is the first in a series of commits over the course
of the next few weeks.
Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.
We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.
Obtained from: //depot/projects/vimage-commit2/...
Reviewed by: brooks, des, ed, mav, julian,
jamie, kris, rwatson, zec, ...
(various people I forgot, different versions)
md5 (with a bit of help)
Sponsored by: NLnet Foundation, The FreeBSD Foundation
X-MFC after: never
V_Commit_Message_Reviewed_By: more people than the patch
2008-08-17 23:27:27 +00:00
|
|
|
if (V_loif == NULL)
|
|
|
|
V_loif = ifp;
|
2002-03-11 09:26:07 +00:00
|
|
|
|
|
|
|
return (0);
|
2001-01-29 11:06:26 +00:00
|
|
|
}
|
|
|
|
|
Introduce and use a sysinit-based initialization scheme for virtual
network stacks, VNET_SYSINIT:
- Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
occur each time a network stack is instantiated and destroyed. In the
!VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
For the VIMAGE case, we instead use SYSINIT's to track their order and
properties on registration, using them for each vnet when created/
destroyed, or immediately on module load for already-started vnets.
- Remove vnet_modinfo mechanism that existed to serve this purpose
previously, as well as its dependency scheme: we now just use the
SYSINIT ordering scheme.
- Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
they want init functions to be called for each virtual network stack
rather than just once at boot, compiling down to DOMAIN_SET() in the
non-VIMAGE case.
- Walk all virtualized kernel subsystems and make use of these instead
of modinfo or DOMAIN_SET() for init/uninit events. In some cases,
convert modular components from using modevent to using sysinit (where
appropriate). In some cases, do minor rejuggling of SYSINIT ordering
to make room for or better manage events.
Portions submitted by: jhb (VNET_SYSINIT), bz (cleanup)
Discussed with: jhb, bz, julian, zec
Reviewed by: bz
Approved by: re (VIMAGE blanket)
2009-07-23 20:46:49 +00:00
|
|
|
static void
|
|
|
|
vnet_loif_init(const void *unused __unused)
|
First pass at separating per-vnet initializer functions
from existing functions for initializing global state.
At this stage, the new per-vnet initializer functions are
directly called from the existing global initialization code,
which should in most cases result in compiler inlining those
new functions, hence yielding a near-zero functional change.
Modify the existing initializer functions which are invoked via
protosw, like ip_init() et. al., to allow them to be invoked
multiple times, i.e. per each vnet. Global state, if any,
is initialized only if such functions are called within the
context of vnet0, which will be determined via the
IS_DEFAULT_VNET(curvnet) check (currently always true).
While here, V_irtualize a few remaining global UMA zones
used by net/netinet/netipsec networking code. While it is
not yet clear to me or anybody else whether this is the right
thing to do, at this stage this makes the code more readable,
and makes it easier to track uncollected UMA-zone-backed
objects on vnet removal. In the long run, it's quite possible
that some form of shared use of UMA zone pools among multiple
vnets should be considered.
Bump __FreeBSD_version due to changes in layout of structs
vnet_ipfw, vnet_inet and vnet_net.
Approved by: julian (mentor)
2009-04-06 22:29:41 +00:00
|
|
|
{
|
|
|
|
|
2009-05-23 21:43:44 +00:00
|
|
|
#ifdef VIMAGE
|
2012-10-16 13:37:54 +00:00
|
|
|
lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
|
|
|
|
1);
|
Introduce and use a sysinit-based initialization scheme for virtual
network stacks, VNET_SYSINIT:
- Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
occur each time a network stack is instantiated and destroyed. In the
!VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
For the VIMAGE case, we instead use SYSINIT's to track their order and
properties on registration, using them for each vnet when created/
destroyed, or immediately on module load for already-started vnets.
- Remove vnet_modinfo mechanism that existed to serve this purpose
previously, as well as its dependency scheme: we now just use the
SYSINIT ordering scheme.
- Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
they want init functions to be called for each virtual network stack
rather than just once at boot, compiling down to DOMAIN_SET() in the
non-VIMAGE case.
- Walk all virtualized kernel subsystems and make use of these instead
of modinfo or DOMAIN_SET() for init/uninit events. In some cases,
convert modular components from using modevent to using sysinit (where
appropriate). In some cases, do minor rejuggling of SYSINIT ordering
to make room for or better manage events.
Portions submitted by: jhb (VNET_SYSINIT), bz (cleanup)
Discussed with: jhb, bz, julian, zec
Reviewed by: bz
Approved by: re (VIMAGE blanket)
2009-07-23 20:46:49 +00:00
|
|
|
V_lo_cloner = lo_cloner;
|
2009-05-23 21:43:44 +00:00
|
|
|
#else
|
2012-10-16 13:37:54 +00:00
|
|
|
lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
|
|
|
|
1);
|
2009-05-23 21:43:44 +00:00
|
|
|
#endif
|
First pass at separating per-vnet initializer functions
from existing functions for initializing global state.
At this stage, the new per-vnet initializer functions are
directly called from the existing global initialization code,
which should in most cases result in compiler inlining those
new functions, hence yielding a near-zero functional change.
Modify the existing initializer functions which are invoked via
protosw, like ip_init() et. al., to allow them to be invoked
multiple times, i.e. per each vnet. Global state, if any,
is initialized only if such functions are called within the
context of vnet0, which will be determined via the
IS_DEFAULT_VNET(curvnet) check (currently always true).
While here, V_irtualize a few remaining global UMA zones
used by net/netinet/netipsec networking code. While it is
not yet clear to me or anybody else whether this is the right
thing to do, at this stage this makes the code more readable,
and makes it easier to track uncollected UMA-zone-backed
objects on vnet removal. In the long run, it's quite possible
that some form of shared use of UMA zone pools among multiple
vnets should be considered.
Bump __FreeBSD_version due to changes in layout of structs
vnet_ipfw, vnet_inet and vnet_net.
Approved by: julian (mentor)
2009-04-06 22:29:41 +00:00
|
|
|
}
|
Get closer to a VIMAGE network stack teardown from top to bottom rather
than removing the network interfaces first. This change is rather larger
and convoluted as the ordering requirements cannot be separated.
Move the pfil(9) framework to SI_SUB_PROTO_PFIL, move Firewalls and
related modules to their own SI_SUB_PROTO_FIREWALL.
Move initialization of "physical" interfaces to SI_SUB_DRIVERS,
move virtual (cloned) interfaces to SI_SUB_PSEUDO.
Move Multicast to SI_SUB_PROTO_MC.
Re-work parts of multicast initialisation and teardown, not taking the
huge amount of memory into account if used as a module yet.
For interface teardown we try to do as many of them as we can on
SI_SUB_INIT_IF, but for some this makes no sense, e.g., when tunnelling
over a higher layer protocol such as IP. In that case the interface
has to go along (or before) the higher layer protocol is shutdown.
Kernel hhooks need to go last on teardown as they may be used at various
higher layers and we cannot remove them before we cleaned up the higher
layers.
For interface teardown there are multiple paths:
(a) a cloned interface is destroyed (inside a VIMAGE or in the base system),
(b) any interface is moved from a virtual network stack to a different
network stack ("vmove"), or (c) a virtual network stack is being shut down.
All code paths go through if_detach_internal() where we, depending on the
vmove flag or the vnet state, make a decision on how much to shut down;
in case we are destroying a VNET the individual protocol layers will
cleanup their own parts thus we cannot do so again for each interface as
we end up with, e.g., double-frees, destroying locks twice or acquiring
already destroyed locks.
When calling into protocol cleanups we equally have to tell them
whether they need to detach upper layer protocols ("ulp") or not
(e.g., in6_ifdetach()).
Provide or enahnce helper functions to do proper cleanup at a protocol
rather than at an interface level.
Approved by: re (hrs)
Obtained from: projects/vnet
Reviewed by: gnn, jhb
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D6747
2016-06-21 13:48:49 +00:00
|
|
|
VNET_SYSINIT(vnet_loif_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
|
Introduce and use a sysinit-based initialization scheme for virtual
network stacks, VNET_SYSINIT:
- Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
occur each time a network stack is instantiated and destroyed. In the
!VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
For the VIMAGE case, we instead use SYSINIT's to track their order and
properties on registration, using them for each vnet when created/
destroyed, or immediately on module load for already-started vnets.
- Remove vnet_modinfo mechanism that existed to serve this purpose
previously, as well as its dependency scheme: we now just use the
SYSINIT ordering scheme.
- Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
they want init functions to be called for each virtual network stack
rather than just once at boot, compiling down to DOMAIN_SET() in the
non-VIMAGE case.
- Walk all virtualized kernel subsystems and make use of these instead
of modinfo or DOMAIN_SET() for init/uninit events. In some cases,
convert modular components from using modevent to using sysinit (where
appropriate). In some cases, do minor rejuggling of SYSINIT ordering
to make room for or better manage events.
Portions submitted by: jhb (VNET_SYSINIT), bz (cleanup)
Discussed with: jhb, bz, julian, zec
Reviewed by: bz
Approved by: re (VIMAGE blanket)
2009-07-23 20:46:49 +00:00
|
|
|
vnet_loif_init, NULL);
|
First pass at separating per-vnet initializer functions
from existing functions for initializing global state.
At this stage, the new per-vnet initializer functions are
directly called from the existing global initialization code,
which should in most cases result in compiler inlining those
new functions, hence yielding a near-zero functional change.
Modify the existing initializer functions which are invoked via
protosw, like ip_init() et. al., to allow them to be invoked
multiple times, i.e. per each vnet. Global state, if any,
is initialized only if such functions are called within the
context of vnet0, which will be determined via the
IS_DEFAULT_VNET(curvnet) check (currently always true).
While here, V_irtualize a few remaining global UMA zones
used by net/netinet/netipsec networking code. While it is
not yet clear to me or anybody else whether this is the right
thing to do, at this stage this makes the code more readable,
and makes it easier to track uncollected UMA-zone-backed
objects on vnet removal. In the long run, it's quite possible
that some form of shared use of UMA zone pools among multiple
vnets should be considered.
Bump __FreeBSD_version due to changes in layout of structs
vnet_ipfw, vnet_inet and vnet_net.
Approved by: julian (mentor)
2009-04-06 22:29:41 +00:00
|
|
|
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
#ifdef VIMAGE
|
Introduce and use a sysinit-based initialization scheme for virtual
network stacks, VNET_SYSINIT:
- Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
occur each time a network stack is instantiated and destroyed. In the
!VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
For the VIMAGE case, we instead use SYSINIT's to track their order and
properties on registration, using them for each vnet when created/
destroyed, or immediately on module load for already-started vnets.
- Remove vnet_modinfo mechanism that existed to serve this purpose
previously, as well as its dependency scheme: we now just use the
SYSINIT ordering scheme.
- Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
they want init functions to be called for each virtual network stack
rather than just once at boot, compiling down to DOMAIN_SET() in the
non-VIMAGE case.
- Walk all virtualized kernel subsystems and make use of these instead
of modinfo or DOMAIN_SET() for init/uninit events. In some cases,
convert modular components from using modevent to using sysinit (where
appropriate). In some cases, do minor rejuggling of SYSINIT ordering
to make room for or better manage events.
Portions submitted by: jhb (VNET_SYSINIT), bz (cleanup)
Discussed with: jhb, bz, julian, zec
Reviewed by: bz
Approved by: re (VIMAGE blanket)
2009-07-23 20:46:49 +00:00
|
|
|
static void
|
|
|
|
vnet_loif_uninit(const void *unused __unused)
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
{
|
|
|
|
|
2012-10-16 13:37:54 +00:00
|
|
|
if_clone_detach(V_lo_cloner);
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
V_loif = NULL;
|
|
|
|
}
|
Get closer to a VIMAGE network stack teardown from top to bottom rather
than removing the network interfaces first. This change is rather larger
and convoluted as the ordering requirements cannot be separated.
Move the pfil(9) framework to SI_SUB_PROTO_PFIL, move Firewalls and
related modules to their own SI_SUB_PROTO_FIREWALL.
Move initialization of "physical" interfaces to SI_SUB_DRIVERS,
move virtual (cloned) interfaces to SI_SUB_PSEUDO.
Move Multicast to SI_SUB_PROTO_MC.
Re-work parts of multicast initialisation and teardown, not taking the
huge amount of memory into account if used as a module yet.
For interface teardown we try to do as many of them as we can on
SI_SUB_INIT_IF, but for some this makes no sense, e.g., when tunnelling
over a higher layer protocol such as IP. In that case the interface
has to go along (or before) the higher layer protocol is shutdown.
Kernel hhooks need to go last on teardown as they may be used at various
higher layers and we cannot remove them before we cleaned up the higher
layers.
For interface teardown there are multiple paths:
(a) a cloned interface is destroyed (inside a VIMAGE or in the base system),
(b) any interface is moved from a virtual network stack to a different
network stack ("vmove"), or (c) a virtual network stack is being shut down.
All code paths go through if_detach_internal() where we, depending on the
vmove flag or the vnet state, make a decision on how much to shut down;
in case we are destroying a VNET the individual protocol layers will
cleanup their own parts thus we cannot do so again for each interface as
we end up with, e.g., double-frees, destroying locks twice or acquiring
already destroyed locks.
When calling into protocol cleanups we equally have to tell them
whether they need to detach upper layer protocols ("ulp") or not
(e.g., in6_ifdetach()).
Provide or enahnce helper functions to do proper cleanup at a protocol
rather than at an interface level.
Approved by: re (hrs)
Obtained from: projects/vnet
Reviewed by: gnn, jhb
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D6747
2016-06-21 13:48:49 +00:00
|
|
|
VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_INIT_IF, SI_ORDER_SECOND,
|
Introduce and use a sysinit-based initialization scheme for virtual
network stacks, VNET_SYSINIT:
- Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
occur each time a network stack is instantiated and destroyed. In the
!VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
For the VIMAGE case, we instead use SYSINIT's to track their order and
properties on registration, using them for each vnet when created/
destroyed, or immediately on module load for already-started vnets.
- Remove vnet_modinfo mechanism that existed to serve this purpose
previously, as well as its dependency scheme: we now just use the
SYSINIT ordering scheme.
- Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
they want init functions to be called for each virtual network stack
rather than just once at boot, compiling down to DOMAIN_SET() in the
non-VIMAGE case.
- Walk all virtualized kernel subsystems and make use of these instead
of modinfo or DOMAIN_SET() for init/uninit events. In some cases,
convert modular components from using modevent to using sysinit (where
appropriate). In some cases, do minor rejuggling of SYSINIT ordering
to make room for or better manage events.
Portions submitted by: jhb (VNET_SYSINIT), bz (cleanup)
Discussed with: jhb, bz, julian, zec
Reviewed by: bz
Approved by: re (VIMAGE blanket)
2009-07-23 20:46:49 +00:00
|
|
|
vnet_loif_uninit, NULL);
|
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor
functions to clean up and release per-module state. The destructor
mechanisms can be triggered by invoking "vimage -d", or a future
equivalent command which will be provided via the new jail framework.
While this patch introduces numerous placeholder destructor functions,
many of those are currently incomplete, thus leaking memory or (even
worse) failing to stop all running timers. Many of such issues are
already known and will be incrementaly fixed over the next weeks in
smaller incremental commits.
Apart from introducing new fields in structs ifnet, domain, protosw
and vnet_net, which requires the kernel and modules to be rebuilt, this
change should have no impact on nooptions VIMAGE builds, since vnet
destructors can only be called in VIMAGE kernels. Moreover,
destructor functions should be in general compiled in only in
options VIMAGE builds, except for kernel modules which can be safely
kldunloaded at run time.
Bump __FreeBSD_version to 800097.
Reviewed by: bz, julian
Approved by: rwatson, kib (re), julian (mentor)
2009-06-08 17:15:40 +00:00
|
|
|
#endif
|
|
|
|
|
2001-01-31 07:58:58 +00:00
|
|
|
static int
|
2008-05-09 20:38:25 +00:00
|
|
|
loop_modevent(module_t mod, int type, void *data)
|
|
|
|
{
|
2008-04-07 01:43:30 +00:00
|
|
|
|
2008-05-09 20:38:25 +00:00
|
|
|
switch (type) {
|
|
|
|
case MOD_LOAD:
|
|
|
|
break;
|
2008-04-07 01:43:30 +00:00
|
|
|
|
2008-05-09 20:38:25 +00:00
|
|
|
case MOD_UNLOAD:
|
|
|
|
printf("loop module unload - not possible for this module type\n");
|
2008-04-07 01:43:30 +00:00
|
|
|
return (EINVAL);
|
|
|
|
|
2004-07-15 08:26:07 +00:00
|
|
|
default:
|
2008-04-07 01:43:30 +00:00
|
|
|
return (EOPNOTSUPP);
|
2008-05-09 20:38:25 +00:00
|
|
|
}
|
2008-04-07 01:43:30 +00:00
|
|
|
return (0);
|
2008-05-09 20:38:25 +00:00
|
|
|
}
|
2001-01-31 07:58:58 +00:00
|
|
|
|
2008-05-09 20:38:25 +00:00
|
|
|
static moduledata_t loop_mod = {
|
2010-02-21 15:25:47 +00:00
|
|
|
"if_lo",
|
2008-05-09 20:38:25 +00:00
|
|
|
loop_modevent,
|
2012-10-10 08:36:38 +00:00
|
|
|
0
|
2008-05-09 20:38:25 +00:00
|
|
|
};
|
2001-01-31 07:58:58 +00:00
|
|
|
|
2010-02-21 15:25:47 +00:00
|
|
|
DECLARE_MODULE(if_lo, loop_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1999-12-07 17:39:16 +00:00
|
|
|
int
|
2013-04-26 12:50:32 +00:00
|
|
|
looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
2009-04-16 20:30:28 +00:00
|
|
|
struct route *ro)
|
1998-06-12 03:48:19 +00:00
|
|
|
{
|
2005-06-26 18:11:11 +00:00
|
|
|
u_int32_t af;
|
2009-01-10 23:50:23 +00:00
|
|
|
#ifdef MAC
|
|
|
|
int error;
|
|
|
|
#endif
|
2005-06-26 18:11:11 +00:00
|
|
|
|
2003-04-08 14:25:47 +00:00
|
|
|
M_ASSERTPKTHDR(m); /* check if we have the packet header */
|
1998-06-12 03:48:19 +00:00
|
|
|
|
2009-01-10 23:50:23 +00:00
|
|
|
#ifdef MAC
|
|
|
|
error = mac_ifnet_check_transmit(ifp, m);
|
|
|
|
if (error) {
|
|
|
|
m_freem(m);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-01-09 16:34:37 +00:00
|
|
|
if (ro != NULL && ro->ro_flags & (RT_REJECT|RT_BLACKHOLE)) {
|
1998-06-12 03:48:19 +00:00
|
|
|
m_freem(m);
|
2016-01-09 16:34:37 +00:00
|
|
|
return (ro->ro_flags & RT_BLACKHOLE ? 0 : EHOSTUNREACH);
|
1998-06-12 03:48:19 +00:00
|
|
|
}
|
1999-11-22 02:45:11 +00:00
|
|
|
|
2014-09-19 10:39:58 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
|
|
|
if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
|
2005-06-26 18:11:11 +00:00
|
|
|
|
|
|
|
/* BPF writes need to be handled specially. */
|
2015-07-06 02:12:49 +00:00
|
|
|
if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
|
2005-06-26 18:11:11 +00:00
|
|
|
bcopy(dst->sa_data, &af, sizeof(af));
|
2013-04-26 12:50:32 +00:00
|
|
|
else
|
|
|
|
af = dst->sa_family;
|
2005-06-26 18:11:11 +00:00
|
|
|
|
1998-06-14 20:58:17 +00:00
|
|
|
#if 1 /* XXX */
|
2013-04-26 12:50:32 +00:00
|
|
|
switch (af) {
|
1998-06-14 20:58:17 +00:00
|
|
|
case AF_INET:
|
2009-03-15 20:17:44 +00:00
|
|
|
if (ifp->if_capenable & IFCAP_RXCSUM) {
|
|
|
|
m->m_pkthdr.csum_data = 0xffff;
|
2009-03-16 10:56:50 +00:00
|
|
|
m->m_pkthdr.csum_flags = LO_CSUM_SET;
|
2009-03-15 20:17:44 +00:00
|
|
|
}
|
2009-03-16 10:56:50 +00:00
|
|
|
m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES;
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2012-07-28 20:31:39 +00:00
|
|
|
#if 0
|
|
|
|
/*
|
|
|
|
* XXX-BZ for now always claim the checksum is good despite
|
|
|
|
* any interface flags. This is a workaround for 9.1-R and
|
|
|
|
* a proper solution ought to be sought later.
|
|
|
|
*/
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
if (ifp->if_capenable & IFCAP_RXCSUM_IPV6) {
|
|
|
|
m->m_pkthdr.csum_data = 0xffff;
|
|
|
|
m->m_pkthdr.csum_flags = LO_CSUM_SET;
|
|
|
|
}
|
2012-07-28 20:31:39 +00:00
|
|
|
#else
|
|
|
|
m->m_pkthdr.csum_data = 0xffff;
|
|
|
|
m->m_pkthdr.csum_flags = LO_CSUM_SET;
|
|
|
|
#endif
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES6;
|
|
|
|
break;
|
1998-06-14 20:58:17 +00:00
|
|
|
default:
|
2013-04-26 12:50:32 +00:00
|
|
|
printf("looutput: af=%d unexpected\n", af);
|
1998-06-14 20:58:17 +00:00
|
|
|
m_freem(m);
|
|
|
|
return (EAFNOSUPPORT);
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-26 12:50:32 +00:00
|
|
|
return (if_simloop(ifp, m, af, 0));
|
1998-06-12 03:48:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* if_simloop()
|
|
|
|
*
|
|
|
|
* This function is to support software emulation of hardware loopback,
|
|
|
|
* i.e., for interfaces with the IFF_SIMPLEX attribute. Since they can't
|
|
|
|
* hear their own broadcasts, we create a copy of the packet that we
|
|
|
|
* would normally receive via a hardware loopback.
|
|
|
|
*
|
|
|
|
* This function expects the packet to include the media header of length hlen.
|
|
|
|
*/
|
|
|
|
int
|
2008-04-07 01:43:30 +00:00
|
|
|
if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
|
1994-05-24 10:09:53 +00:00
|
|
|
{
|
Lock down the network interface queues. The queue mutex must be obtained
before adding/removing packets from the queue. Also, the if_obytes and
if_omcasts fields should only be manipulated under protection of the mutex.
IF_ENQUEUE, IF_PREPEND, and IF_DEQUEUE perform all necessary locking on
the queue. An IF_LOCK macro is provided, as well as the old (mutex-less)
versions of the macros in the form _IF_ENQUEUE, _IF_QFULL, for code which
needs them, but their use is discouraged.
Two new macros are introduced: IF_DRAIN() to drain a queue, and IF_HANDOFF,
which takes care of locking/enqueue, and also statistics updating/start
if necessary.
2000-11-25 07:35:38 +00:00
|
|
|
int isr;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2003-04-08 14:25:47 +00:00
|
|
|
M_ASSERTPKTHDR(m);
|
2003-10-29 05:40:07 +00:00
|
|
|
m_tag_delete_nonpersistent(m);
|
1998-06-12 03:48:19 +00:00
|
|
|
m->m_pkthdr.rcvif = ifp;
|
2000-05-24 21:16:56 +00:00
|
|
|
|
2009-01-10 23:50:23 +00:00
|
|
|
#ifdef MAC
|
|
|
|
mac_ifnet_create_mbuf(ifp, m);
|
|
|
|
#endif
|
|
|
|
|
2006-09-22 01:31:22 +00:00
|
|
|
/*
|
|
|
|
* Let BPF see incoming packet in the following manner:
|
2008-05-09 20:38:25 +00:00
|
|
|
* - Emulated packet loopback for a simplex interface
|
2006-09-22 01:31:22 +00:00
|
|
|
* (net/if_ethersubr.c)
|
|
|
|
* -> passes it to ifp's BPF
|
|
|
|
* - IPv4/v6 multicast packet loopback (netinet(6)/ip(6)_output.c)
|
|
|
|
* -> not passes it to any BPF
|
|
|
|
* - Normal packet loopback from myself to myself (net/if_loop.c)
|
|
|
|
* -> passes to lo0's BPF (even in case of IPv6, where ifp!=lo0)
|
|
|
|
*/
|
|
|
|
if (hlen > 0) {
|
|
|
|
if (bpf_peers_present(ifp->if_bpf)) {
|
2003-12-28 03:56:00 +00:00
|
|
|
bpf_mtap(ifp->if_bpf, m);
|
2006-09-22 01:31:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).
This is the first in a series of commits over the course
of the next few weeks.
Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.
We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.
Obtained from: //depot/projects/vimage-commit2/...
Reviewed by: brooks, des, ed, mav, julian,
jamie, kris, rwatson, zec, ...
(various people I forgot, different versions)
md5 (with a bit of help)
Sponsored by: NLnet Foundation, The FreeBSD Foundation
X-MFC after: never
V_Commit_Message_Reviewed_By: more people than the patch
2008-08-17 23:27:27 +00:00
|
|
|
if (bpf_peers_present(V_loif->if_bpf)) {
|
|
|
|
if ((m->m_flags & M_MCAST) == 0 || V_loif == ifp) {
|
2006-09-22 01:31:22 +00:00
|
|
|
/* XXX beware sizeof(af) != 4 */
|
2008-08-01 09:41:45 +00:00
|
|
|
u_int32_t af1 = af;
|
2006-09-22 01:31:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to prepend the address family.
|
|
|
|
*/
|
Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).
This is the first in a series of commits over the course
of the next few weeks.
Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.
We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.
Obtained from: //depot/projects/vimage-commit2/...
Reviewed by: brooks, des, ed, mav, julian,
jamie, kris, rwatson, zec, ...
(various people I forgot, different versions)
md5 (with a bit of help)
Sponsored by: NLnet Foundation, The FreeBSD Foundation
X-MFC after: never
V_Commit_Message_Reviewed_By: more people than the patch
2008-08-17 23:27:27 +00:00
|
|
|
bpf_mtap2(V_loif->if_bpf, &af1, sizeof(af1), m);
|
2006-09-22 01:31:22 +00:00
|
|
|
}
|
|
|
|
}
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
|
|
|
|
1998-06-12 03:48:19 +00:00
|
|
|
/* Strip away media header */
|
1998-07-12 16:46:52 +00:00
|
|
|
if (hlen > 0) {
|
2000-05-26 13:47:02 +00:00
|
|
|
m_adj(m, hlen);
|
2007-02-09 00:09:35 +00:00
|
|
|
#ifndef __NO_STRICT_ALIGNMENT
|
2006-05-12 05:04:46 +00:00
|
|
|
/*
|
|
|
|
* Some archs do not like unaligned data, so
|
|
|
|
* we move data down in the first mbuf.
|
|
|
|
*/
|
2000-05-26 13:47:02 +00:00
|
|
|
if (mtod(m, vm_offset_t) & 3) {
|
2000-06-02 19:06:33 +00:00
|
|
|
KASSERT(hlen >= 3, ("if_simloop: hlen too small"));
|
2008-05-09 20:38:25 +00:00
|
|
|
bcopy(m->m_data,
|
|
|
|
(char *)(mtod(m, vm_offset_t)
|
2000-05-26 13:47:02 +00:00
|
|
|
- (mtod(m, vm_offset_t) & 3)),
|
|
|
|
m->m_len);
|
2004-07-28 06:59:55 +00:00
|
|
|
m->m_data -= (mtod(m,vm_offset_t) & 3);
|
2000-05-26 13:47:02 +00:00
|
|
|
}
|
1998-07-12 16:46:52 +00:00
|
|
|
#endif
|
|
|
|
}
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2000-05-24 21:16:56 +00:00
|
|
|
/* Deliver to upper layer protocol */
|
|
|
|
switch (af) {
|
1994-05-24 10:09:53 +00:00
|
|
|
#ifdef INET
|
|
|
|
case AF_INET:
|
|
|
|
isr = NETISR_IP;
|
|
|
|
break;
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
m->m_flags |= M_LOOP;
|
|
|
|
isr = NETISR_IPV6;
|
|
|
|
break;
|
2001-09-10 01:33:03 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
default:
|
2000-05-24 21:16:56 +00:00
|
|
|
printf("if_simloop: can't handle af=%d\n", af);
|
1994-05-24 10:09:53 +00:00
|
|
|
m_freem(m);
|
|
|
|
return (EAFNOSUPPORT);
|
|
|
|
}
|
2014-09-19 10:39:58 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
|
|
|
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
|
2004-08-27 18:33:08 +00:00
|
|
|
netisr_queue(isr, m); /* mbuf is free'd on failure. */
|
1994-05-24 10:09:53 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process an ioctl request.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1999-12-07 17:39:16 +00:00
|
|
|
int
|
2008-04-07 01:43:30 +00:00
|
|
|
loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
1994-05-24 10:09:53 +00:00
|
|
|
{
|
2008-04-07 01:43:30 +00:00
|
|
|
struct ifreq *ifr = (struct ifreq *)data;
|
2009-03-15 20:17:44 +00:00
|
|
|
int error = 0, mask;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case SIOCSIFADDR:
|
2005-08-09 10:20:02 +00:00
|
|
|
ifp->if_flags |= IFF_UP;
|
|
|
|
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
|
|
|
* Everything else is done at a higher level.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIOCADDMULTI:
|
|
|
|
case SIOCDELMULTI:
|
2016-04-15 17:30:33 +00:00
|
|
|
if (ifr == NULL) {
|
1994-05-24 10:09:53 +00:00
|
|
|
error = EAFNOSUPPORT; /* XXX */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (ifr->ifr_addr.sa_family) {
|
|
|
|
|
|
|
|
#ifdef INET
|
|
|
|
case AF_INET:
|
|
|
|
break;
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
break;
|
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
error = EAFNOSUPPORT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1994-08-08 12:09:04 +00:00
|
|
|
case SIOCSIFMTU:
|
1999-08-06 16:46:29 +00:00
|
|
|
ifp->if_mtu = ifr->ifr_mtu;
|
1994-08-08 12:09:04 +00:00
|
|
|
break;
|
|
|
|
|
1998-04-30 19:37:00 +00:00
|
|
|
case SIOCSIFFLAGS:
|
|
|
|
break;
|
|
|
|
|
2009-03-15 20:17:44 +00:00
|
|
|
case SIOCSIFCAP:
|
|
|
|
mask = ifp->if_capenable ^ ifr->ifr_reqcap;
|
|
|
|
if ((mask & IFCAP_RXCSUM) != 0)
|
|
|
|
ifp->if_capenable ^= IFCAP_RXCSUM;
|
|
|
|
if ((mask & IFCAP_TXCSUM) != 0)
|
|
|
|
ifp->if_capenable ^= IFCAP_TXCSUM;
|
2012-07-28 20:31:39 +00:00
|
|
|
if ((mask & IFCAP_RXCSUM_IPV6) != 0) {
|
|
|
|
#if 0
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
|
2012-07-28 20:31:39 +00:00
|
|
|
#else
|
|
|
|
error = EOPNOTSUPP;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if ((mask & IFCAP_TXCSUM_IPV6) != 0) {
|
|
|
|
#if 0
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
|
2012-07-28 20:31:39 +00:00
|
|
|
#else
|
|
|
|
error = EOPNOTSUPP;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
ifp->if_hwassist = 0;
|
2009-03-15 20:17:44 +00:00
|
|
|
if (ifp->if_capenable & IFCAP_TXCSUM)
|
2009-03-16 10:56:50 +00:00
|
|
|
ifp->if_hwassist = LO_CSUM_FEATURES;
|
2012-07-28 20:31:39 +00:00
|
|
|
#if 0
|
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
2012-05-28 09:30:13 +00:00
|
|
|
if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
|
|
|
|
ifp->if_hwassist |= LO_CSUM_FEATURES6;
|
2012-07-28 20:31:39 +00:00
|
|
|
#endif
|
2009-03-15 20:17:44 +00:00
|
|
|
break;
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
default:
|
|
|
|
error = EINVAL;
|
|
|
|
}
|
|
|
|
return (error);
|
|
|
|
}
|