2005-01-07 02:30:35 +00:00
|
|
|
/*-
|
1999-11-22 02:45:11 +00:00
|
|
|
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
|
|
|
* 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.
|
|
|
|
* 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
|
2007-12-10 16:03:40 +00:00
|
|
|
*
|
|
|
|
* $KAME: frag6.c,v 1.33 2002/01/07 11:34:48 kjc Exp $
|
1999-11-22 02:45:11 +00:00
|
|
|
*/
|
|
|
|
|
2007-12-10 16:03:40 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2015-11-06 23:07:43 +00:00
|
|
|
#include "opt_rss.h"
|
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/mbuf.h>
|
|
|
|
#include <sys/domain.h>
|
2016-01-09 09:34:39 +00:00
|
|
|
#include <sys/eventhandler.h>
|
1999-11-22 02:45:11 +00:00
|
|
|
#include <sys/protosw.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/errno.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/syslog.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
2013-10-26 17:58:36 +00:00
|
|
|
#include <net/if_var.h>
|
2015-11-06 23:07:43 +00:00
|
|
|
#include <net/netisr.h>
|
1999-11-22 02:45:11 +00:00
|
|
|
#include <net/route.h>
|
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
|
|
|
#include <net/vnet.h>
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_var.h>
|
2000-07-04 16:35:15 +00:00
|
|
|
#include <netinet/ip6.h>
|
1999-11-22 02:45:11 +00:00
|
|
|
#include <netinet6/ip6_var.h>
|
2000-07-04 16:35:15 +00:00
|
|
|
#include <netinet/icmp6.h>
|
2003-10-29 15:07:04 +00:00
|
|
|
#include <netinet/in_systm.h> /* for ECN definitions */
|
|
|
|
#include <netinet/ip.h> /* for ECN definitions */
|
1999-11-22 02:45:11 +00:00
|
|
|
|
2008-10-26 22:45:18 +00:00
|
|
|
#include <security/mac/mac_framework.h>
|
|
|
|
|
2008-01-08 19:08:58 +00:00
|
|
|
static void frag6_enq(struct ip6asfrag *, struct ip6asfrag *);
|
|
|
|
static void frag6_deq(struct ip6asfrag *);
|
|
|
|
static void frag6_insque(struct ip6q *, struct ip6q *);
|
|
|
|
static void frag6_remque(struct ip6q *);
|
|
|
|
static void frag6_freef(struct ip6q *);
|
1999-11-22 02:45:11 +00:00
|
|
|
|
2003-10-22 15:32:56 +00:00
|
|
|
static struct mtx ip6qlock;
|
|
|
|
/*
|
|
|
|
* These fields all protected by ip6qlock.
|
|
|
|
*/
|
2010-11-22 19:32:54 +00:00
|
|
|
static VNET_DEFINE(u_int, frag6_nfragpackets);
|
|
|
|
static VNET_DEFINE(u_int, frag6_nfrags);
|
|
|
|
static VNET_DEFINE(struct ip6q, ip6q); /* ip6 reassemble queue */
|
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
|
|
|
|
2009-07-16 21:13:04 +00:00
|
|
|
#define V_frag6_nfragpackets VNET(frag6_nfragpackets)
|
|
|
|
#define V_frag6_nfrags VNET(frag6_nfrags)
|
|
|
|
#define V_ip6q VNET(ip6q)
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2003-10-22 15:32:56 +00:00
|
|
|
#define IP6Q_LOCK_INIT() mtx_init(&ip6qlock, "ip6qlock", NULL, MTX_DEF);
|
|
|
|
#define IP6Q_LOCK() mtx_lock(&ip6qlock)
|
|
|
|
#define IP6Q_TRYLOCK() mtx_trylock(&ip6qlock)
|
2003-10-22 19:03:49 +00:00
|
|
|
#define IP6Q_LOCK_ASSERT() mtx_assert(&ip6qlock, MA_OWNED)
|
2003-10-22 15:32:56 +00:00
|
|
|
#define IP6Q_UNLOCK() mtx_unlock(&ip6qlock)
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2000-12-08 20:09:00 +00:00
|
|
|
static MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
|
2000-07-04 16:35:15 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* Initialise reassembly queue and fragment identifier.
|
|
|
|
*/
|
2006-04-21 09:25:40 +00:00
|
|
|
static void
|
|
|
|
frag6_change(void *tag)
|
|
|
|
{
|
|
|
|
|
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
|
|
|
V_ip6_maxfragpackets = nmbclusters / 4;
|
|
|
|
V_ip6_maxfrags = nmbclusters / 4;
|
2006-04-21 09:25:40 +00:00
|
|
|
}
|
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_init(void)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
|
|
|
|
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
|
|
|
V_ip6_maxfragpackets = nmbclusters / 4;
|
|
|
|
V_ip6_maxfrags = nmbclusters / 4;
|
2010-04-29 11:52:42 +00:00
|
|
|
V_ip6q.ip6q_next = V_ip6q.ip6q_prev = &V_ip6q;
|
2001-06-10 11:04:10 +00:00
|
|
|
|
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
|
|
|
if (!IS_DEFAULT_VNET(curvnet))
|
|
|
|
return;
|
2003-10-22 15:32:56 +00:00
|
|
|
|
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
|
|
|
EVENTHANDLER_REGISTER(nmbclusters_change,
|
|
|
|
frag6_change, NULL, EVENTHANDLER_PRI_ANY);
|
2010-04-29 11:52:42 +00:00
|
|
|
|
|
|
|
IP6Q_LOCK_INIT();
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
2000-07-04 16:35:15 +00:00
|
|
|
/*
|
|
|
|
* In RFC2460, fragment and reassembly rule do not agree with each other,
|
|
|
|
* in terms of next header field handling in fragment header.
|
|
|
|
* While the sender will use the same value for all of the fragmented packets,
|
|
|
|
* receiver is suggested not to check the consistency.
|
|
|
|
*
|
|
|
|
* fragment rule (p20):
|
|
|
|
* (2) A Fragment header containing:
|
|
|
|
* The Next Header value that identifies the first header of
|
|
|
|
* the Fragmentable Part of the original packet.
|
|
|
|
* -> next header field is same for all fragments
|
|
|
|
*
|
|
|
|
* reassembly rule (p21):
|
|
|
|
* The Next Header field of the last header of the Unfragmentable
|
|
|
|
* Part is obtained from the Next Header field of the first
|
|
|
|
* fragment's Fragment header.
|
|
|
|
* -> should grab it from the first fragment only
|
|
|
|
*
|
|
|
|
* The following note also contradicts with fragment rule - noone is going to
|
|
|
|
* send different fragment with different next header field.
|
|
|
|
*
|
|
|
|
* additional note (p22):
|
|
|
|
* The Next Header values in the Fragment headers of different
|
|
|
|
* fragments of the same original packet may differ. Only the value
|
|
|
|
* from the Offset zero fragment packet is used for reassembly.
|
|
|
|
* -> should grab it from the first fragment only
|
|
|
|
*
|
|
|
|
* There is no explicit reason given in the RFC. Historical reason maybe?
|
|
|
|
*/
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* Fragment input
|
|
|
|
*/
|
|
|
|
int
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_input(struct mbuf **mp, int *offp, int proto)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
|
|
|
struct mbuf *m = *mp, *t;
|
|
|
|
struct ip6_hdr *ip6;
|
|
|
|
struct ip6_frag *ip6f;
|
|
|
|
struct ip6q *q6;
|
2000-07-04 16:35:15 +00:00
|
|
|
struct ip6asfrag *af6, *ip6af, *af6dwn;
|
2003-10-28 16:29:26 +00:00
|
|
|
struct in6_ifaddr *ia;
|
1999-11-22 02:45:11 +00:00
|
|
|
int offset = *offp, nxt, i, next;
|
|
|
|
int first_frag = 0;
|
2000-07-04 16:35:15 +00:00
|
|
|
int fragoff, frgpartlen; /* must be larger than u_int16_t */
|
1999-11-22 02:45:11 +00:00
|
|
|
struct ifnet *dstifp;
|
2003-10-29 15:07:04 +00:00
|
|
|
u_int8_t ecn, ecn0;
|
2015-11-06 23:07:43 +00:00
|
|
|
#ifdef RSS
|
|
|
|
struct m_tag *mtag;
|
|
|
|
struct ip6_direct_ctx *ip6dc;
|
|
|
|
#endif
|
|
|
|
|
2006-12-12 12:17:58 +00:00
|
|
|
#if 0
|
|
|
|
char ip6buf[INET6_ADDRSTRLEN];
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
ip6 = mtod(m, struct ip6_hdr *);
|
2000-07-04 16:35:15 +00:00
|
|
|
#ifndef PULLDOWN_TEST
|
|
|
|
IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
|
1999-11-22 02:45:11 +00:00
|
|
|
ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
|
2000-07-04 16:35:15 +00:00
|
|
|
#else
|
|
|
|
IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f));
|
|
|
|
if (ip6f == NULL)
|
2003-10-06 14:02:09 +00:00
|
|
|
return (IPPROTO_DONE);
|
2000-07-04 16:35:15 +00:00
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
dstifp = NULL;
|
|
|
|
/* find the destination interface of the packet. */
|
2014-11-08 19:38:34 +00:00
|
|
|
ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
|
|
|
|
if (ia != NULL) {
|
2003-10-28 16:29:26 +00:00
|
|
|
dstifp = ia->ia_ifp;
|
2009-06-23 20:19:09 +00:00
|
|
|
ifa_free(&ia->ia_ifa);
|
|
|
|
}
|
1999-11-22 02:45:11 +00:00
|
|
|
/* jumbo payload can't contain a fragment header */
|
|
|
|
if (ip6->ip6_plen == 0) {
|
|
|
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset);
|
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
|
|
|
return IPPROTO_DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check whether fragment packet's fragment length is
|
|
|
|
* multiple of 8 octets.
|
|
|
|
* sizeof(struct ip6_frag) == 8
|
|
|
|
* sizeof(struct ip6_hdr) = 40
|
|
|
|
*/
|
|
|
|
if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
|
|
|
|
(((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
|
2003-10-07 17:46:18 +00:00
|
|
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
|
|
|
offsetof(struct ip6_hdr, ip6_plen));
|
1999-11-22 02:45:11 +00:00
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
|
|
|
return IPPROTO_DONE;
|
|
|
|
}
|
|
|
|
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_fragments);
|
1999-11-22 02:45:11 +00:00
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_reqd);
|
2003-10-07 17:46:18 +00:00
|
|
|
|
2000-07-04 16:35:15 +00:00
|
|
|
/* offset now points to data portion */
|
1999-11-22 02:45:11 +00:00
|
|
|
offset += sizeof(struct ip6_frag);
|
|
|
|
|
2012-07-08 15:30:24 +00:00
|
|
|
/*
|
2013-09-22 14:53:07 +00:00
|
|
|
* RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
|
|
|
|
* upfront, unrelated to any reassembly. Just skip the fragment header.
|
2012-07-08 15:30:24 +00:00
|
|
|
*/
|
|
|
|
if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
|
|
|
|
/* XXX-BZ we want dedicated counters for this. */
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_reassembled);
|
2012-07-08 15:30:24 +00:00
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_ok);
|
|
|
|
*offp = offset;
|
|
|
|
return (ip6f->ip6f_nxt);
|
|
|
|
}
|
|
|
|
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_LOCK();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enforce upper bound on number of fragments.
|
|
|
|
* If maxfrag is 0, never accept fragments.
|
|
|
|
* If maxfrag is -1, accept all fragments without limitation.
|
|
|
|
*/
|
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_ip6_maxfrags < 0)
|
2003-10-22 15:29:42 +00:00
|
|
|
;
|
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
|
|
|
else if (V_frag6_nfrags >= (u_int)V_ip6_maxfrags)
|
2003-10-22 15:29:42 +00:00
|
|
|
goto dropfrag;
|
2001-06-11 12:39:29 +00:00
|
|
|
|
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
|
|
|
for (q6 = V_ip6q.ip6q_next; q6 != &V_ip6q; q6 = q6->ip6q_next)
|
1999-11-22 02:45:11 +00:00
|
|
|
if (ip6f->ip6f_ident == q6->ip6q_ident &&
|
|
|
|
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
|
2008-10-26 22:45:18 +00:00
|
|
|
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst)
|
|
|
|
#ifdef MAC
|
|
|
|
&& mac_ip6q_match(m, q6)
|
|
|
|
#endif
|
|
|
|
)
|
1999-11-22 02:45:11 +00:00
|
|
|
break;
|
|
|
|
|
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 (q6 == &V_ip6q) {
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* the first fragment to arrive, create a reassembly queue.
|
|
|
|
*/
|
|
|
|
first_frag = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enforce upper bound on number of fragmented packets
|
|
|
|
* for which we attempt reassembly;
|
2003-10-22 15:29:42 +00:00
|
|
|
* If maxfragpackets is 0, never accept fragments.
|
|
|
|
* If maxfragpackets is -1, accept all fragments without
|
|
|
|
* limitation.
|
1999-11-22 02:45:11 +00:00
|
|
|
*/
|
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_ip6_maxfragpackets < 0)
|
2001-06-11 12:39:29 +00:00
|
|
|
;
|
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
|
|
|
else if (V_frag6_nfragpackets >= (u_int)V_ip6_maxfragpackets)
|
2001-06-11 12:39:29 +00:00
|
|
|
goto dropfrag;
|
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
|
|
|
V_frag6_nfragpackets++;
|
1999-11-22 02:45:11 +00:00
|
|
|
q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
|
2003-10-27 07:15:22 +00:00
|
|
|
M_NOWAIT);
|
1999-11-22 02:45:11 +00:00
|
|
|
if (q6 == NULL)
|
|
|
|
goto dropfrag;
|
2000-07-04 16:35:15 +00:00
|
|
|
bzero(q6, sizeof(*q6));
|
2008-10-26 22:45:18 +00:00
|
|
|
#ifdef MAC
|
|
|
|
if (mac_ip6q_init(q6, M_NOWAIT) != 0) {
|
|
|
|
free(q6, M_FTABLE);
|
|
|
|
goto dropfrag;
|
|
|
|
}
|
|
|
|
mac_ip6q_create(m, q6);
|
|
|
|
#endif
|
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
|
|
|
frag6_insque(q6, &V_ip6q);
|
1999-11-22 02:45:11 +00:00
|
|
|
|
2000-07-04 16:35:15 +00:00
|
|
|
/* ip6q_nxt will be filled afterwards, from 1st fragment */
|
1999-11-22 02:45:11 +00:00
|
|
|
q6->ip6q_down = q6->ip6q_up = (struct ip6asfrag *)q6;
|
2000-07-04 16:35:15 +00:00
|
|
|
#ifdef notyet
|
|
|
|
q6->ip6q_nxtp = (u_char *)nxtp;
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
q6->ip6q_ident = ip6f->ip6f_ident;
|
2007-07-05 16:29:40 +00:00
|
|
|
q6->ip6q_ttl = IPV6_FRAGTTL;
|
1999-11-22 02:45:11 +00:00
|
|
|
q6->ip6q_src = ip6->ip6_src;
|
|
|
|
q6->ip6q_dst = ip6->ip6_dst;
|
2007-06-04 06:06:35 +00:00
|
|
|
q6->ip6q_ecn =
|
|
|
|
(ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
|
1999-11-22 02:45:11 +00:00
|
|
|
q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */
|
2003-10-22 15:29:42 +00:00
|
|
|
|
|
|
|
q6->ip6q_nfrag = 0;
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If it's the 1st fragment, record the length of the
|
|
|
|
* unfragmentable part and the next header of the fragment header.
|
|
|
|
*/
|
|
|
|
fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
|
|
|
|
if (fragoff == 0) {
|
2003-10-07 17:46:18 +00:00
|
|
|
q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) -
|
|
|
|
sizeof(struct ip6_frag);
|
1999-11-22 02:45:11 +00:00
|
|
|
q6->ip6q_nxt = ip6f->ip6f_nxt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that the reassembled packet would not exceed 65535 bytes
|
|
|
|
* in size.
|
|
|
|
* If it would exceed, discard the fragment and return an ICMP error.
|
|
|
|
*/
|
2000-07-04 16:35:15 +00:00
|
|
|
frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
|
1999-11-22 02:45:11 +00:00
|
|
|
if (q6->ip6q_unfrglen >= 0) {
|
|
|
|
/* The 1st fragment has already arrived. */
|
|
|
|
if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
|
|
|
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
2003-10-07 17:46:18 +00:00
|
|
|
offset - sizeof(struct ip6_frag) +
|
|
|
|
offsetof(struct ip6_frag, ip6f_offlg));
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
2003-10-06 14:02:09 +00:00
|
|
|
return (IPPROTO_DONE);
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
2003-10-07 17:46:18 +00:00
|
|
|
} else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
|
1999-11-22 02:45:11 +00:00
|
|
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
2003-10-07 17:46:18 +00:00
|
|
|
offset - sizeof(struct ip6_frag) +
|
|
|
|
offsetof(struct ip6_frag, ip6f_offlg));
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
2003-10-06 14:02:09 +00:00
|
|
|
return (IPPROTO_DONE);
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If it's the first fragment, do the above check for each
|
|
|
|
* fragment already stored in the reassembly queue.
|
|
|
|
*/
|
|
|
|
if (fragoff == 0) {
|
|
|
|
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
|
|
|
af6 = af6dwn) {
|
|
|
|
af6dwn = af6->ip6af_down;
|
|
|
|
|
|
|
|
if (q6->ip6q_unfrglen + af6->ip6af_off + af6->ip6af_frglen >
|
|
|
|
IPV6_MAXPACKET) {
|
|
|
|
struct mbuf *merr = IP6_REASS_MBUF(af6);
|
|
|
|
struct ip6_hdr *ip6err;
|
|
|
|
int erroff = af6->ip6af_offset;
|
|
|
|
|
|
|
|
/* dequeue the fragment. */
|
|
|
|
frag6_deq(af6);
|
2000-07-04 16:35:15 +00:00
|
|
|
free(af6, M_FTABLE);
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
/* adjust pointer. */
|
|
|
|
ip6err = mtod(merr, struct ip6_hdr *);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Restore source and destination addresses
|
|
|
|
* in the erroneous IPv6 header.
|
|
|
|
*/
|
|
|
|
ip6err->ip6_src = q6->ip6q_src;
|
|
|
|
ip6err->ip6_dst = q6->ip6q_dst;
|
|
|
|
|
|
|
|
icmp6_error(merr, ICMP6_PARAM_PROB,
|
2003-10-07 17:46:18 +00:00
|
|
|
ICMP6_PARAMPROB_HEADER,
|
|
|
|
erroff - sizeof(struct ip6_frag) +
|
|
|
|
offsetof(struct ip6_frag, ip6f_offlg));
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-04 16:35:15 +00:00
|
|
|
ip6af = (struct ip6asfrag *)malloc(sizeof(struct ip6asfrag), M_FTABLE,
|
2003-10-27 07:15:22 +00:00
|
|
|
M_NOWAIT);
|
2000-07-04 16:35:15 +00:00
|
|
|
if (ip6af == NULL)
|
|
|
|
goto dropfrag;
|
|
|
|
bzero(ip6af, sizeof(*ip6af));
|
1999-11-22 02:45:11 +00:00
|
|
|
ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG;
|
|
|
|
ip6af->ip6af_off = fragoff;
|
|
|
|
ip6af->ip6af_frglen = frgpartlen;
|
|
|
|
ip6af->ip6af_offset = offset;
|
|
|
|
IP6_REASS_MBUF(ip6af) = m;
|
|
|
|
|
|
|
|
if (first_frag) {
|
|
|
|
af6 = (struct ip6asfrag *)q6;
|
|
|
|
goto insert;
|
|
|
|
}
|
|
|
|
|
2003-10-29 15:07:04 +00:00
|
|
|
/*
|
|
|
|
* Handle ECN by comparing this segment with the first one;
|
|
|
|
* if CE is set, do not lose CE.
|
|
|
|
* drop if CE and not-ECT are mixed for the same packet.
|
|
|
|
*/
|
|
|
|
ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
|
2007-06-04 06:06:35 +00:00
|
|
|
ecn0 = q6->ip6q_ecn;
|
2003-10-29 15:07:04 +00:00
|
|
|
if (ecn == IPTOS_ECN_CE) {
|
|
|
|
if (ecn0 == IPTOS_ECN_NOTECT) {
|
|
|
|
free(ip6af, M_FTABLE);
|
|
|
|
goto dropfrag;
|
|
|
|
}
|
|
|
|
if (ecn0 != IPTOS_ECN_CE)
|
2007-06-04 06:06:35 +00:00
|
|
|
q6->ip6q_ecn = IPTOS_ECN_CE;
|
2003-10-29 15:07:04 +00:00
|
|
|
}
|
|
|
|
if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT) {
|
|
|
|
free(ip6af, M_FTABLE);
|
|
|
|
goto dropfrag;
|
|
|
|
}
|
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* Find a segment which begins after this one does.
|
|
|
|
*/
|
|
|
|
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
|
|
|
af6 = af6->ip6af_down)
|
|
|
|
if (af6->ip6af_off > ip6af->ip6af_off)
|
|
|
|
break;
|
|
|
|
|
2000-07-04 16:35:15 +00:00
|
|
|
#if 0
|
|
|
|
/*
|
|
|
|
* If there is a preceding segment, it may provide some of
|
|
|
|
* our data already. If so, drop the data from the incoming
|
|
|
|
* segment. If it provides all of our data, drop us.
|
|
|
|
*/
|
|
|
|
if (af6->ip6af_up != (struct ip6asfrag *)q6) {
|
|
|
|
i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
|
|
|
|
- ip6af->ip6af_off;
|
|
|
|
if (i > 0) {
|
|
|
|
if (i >= ip6af->ip6af_frglen)
|
|
|
|
goto dropfrag;
|
|
|
|
m_adj(IP6_REASS_MBUF(ip6af), i);
|
|
|
|
ip6af->ip6af_off += i;
|
|
|
|
ip6af->ip6af_frglen -= i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* While we overlap succeeding segments trim them or,
|
|
|
|
* if they are completely covered, dequeue them.
|
|
|
|
*/
|
|
|
|
while (af6 != (struct ip6asfrag *)q6 &&
|
|
|
|
ip6af->ip6af_off + ip6af->ip6af_frglen > af6->ip6af_off) {
|
|
|
|
i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
|
|
|
|
if (i < af6->ip6af_frglen) {
|
|
|
|
af6->ip6af_frglen -= i;
|
|
|
|
af6->ip6af_off += i;
|
|
|
|
m_adj(IP6_REASS_MBUF(af6), i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
af6 = af6->ip6af_down;
|
|
|
|
m_freem(IP6_REASS_MBUF(af6->ip6af_up));
|
|
|
|
frag6_deq(af6->ip6af_up);
|
|
|
|
}
|
|
|
|
#else
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* If the incoming framgent overlaps some existing fragments in
|
|
|
|
* the reassembly queue, drop it, since it is dangerous to override
|
|
|
|
* existing fragments from a security point of view.
|
2003-10-22 15:29:42 +00:00
|
|
|
* We don't know which fragment is the bad guy - here we trust
|
|
|
|
* fragment that came in earlier, with no real reason.
|
2007-06-04 06:06:35 +00:00
|
|
|
*
|
|
|
|
* Note: due to changes after disabling this part, mbuf passed to
|
|
|
|
* m_adj() below now does not meet the requirement.
|
1999-11-22 02:45:11 +00:00
|
|
|
*/
|
|
|
|
if (af6->ip6af_up != (struct ip6asfrag *)q6) {
|
|
|
|
i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
|
|
|
|
- ip6af->ip6af_off;
|
|
|
|
if (i > 0) {
|
2001-05-20 15:33:46 +00:00
|
|
|
#if 0 /* suppress the noisy log */
|
1999-11-22 02:45:11 +00:00
|
|
|
log(LOG_ERR, "%d bytes of a fragment from %s "
|
|
|
|
"overlaps the previous fragment\n",
|
2006-12-12 12:17:58 +00:00
|
|
|
i, ip6_sprintf(ip6buf, &q6->ip6q_src));
|
2001-05-20 15:33:46 +00:00
|
|
|
#endif
|
|
|
|
free(ip6af, M_FTABLE);
|
1999-11-22 02:45:11 +00:00
|
|
|
goto dropfrag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (af6 != (struct ip6asfrag *)q6) {
|
|
|
|
i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
|
|
|
|
if (i > 0) {
|
2001-05-20 15:33:46 +00:00
|
|
|
#if 0 /* suppress the noisy log */
|
1999-11-22 02:45:11 +00:00
|
|
|
log(LOG_ERR, "%d bytes of a fragment from %s "
|
|
|
|
"overlaps the succeeding fragment",
|
2006-12-12 12:17:58 +00:00
|
|
|
i, ip6_sprintf(ip6buf, &q6->ip6q_src));
|
2001-05-20 15:33:46 +00:00
|
|
|
#endif
|
|
|
|
free(ip6af, M_FTABLE);
|
1999-11-22 02:45:11 +00:00
|
|
|
goto dropfrag;
|
|
|
|
}
|
|
|
|
}
|
2000-07-04 16:35:15 +00:00
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
insert:
|
2008-10-26 22:45:18 +00:00
|
|
|
#ifdef MAC
|
|
|
|
if (!first_frag)
|
|
|
|
mac_ip6q_update(m, q6);
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Stick new segment in its place;
|
|
|
|
* check for complete reassembly.
|
|
|
|
* Move to front of packet queue, as we are
|
|
|
|
* the most recently active fragmented packet.
|
|
|
|
*/
|
|
|
|
frag6_enq(ip6af, af6->ip6af_up);
|
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
|
|
|
V_frag6_nfrags++;
|
2003-10-22 15:29:42 +00:00
|
|
|
q6->ip6q_nfrag++;
|
2000-07-04 16:35:15 +00:00
|
|
|
#if 0 /* xxx */
|
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 (q6 != V_ip6q.ip6q_next) {
|
2000-07-04 16:35:15 +00:00
|
|
|
frag6_remque(q6);
|
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
|
|
|
frag6_insque(q6, &V_ip6q);
|
2000-07-04 16:35:15 +00:00
|
|
|
}
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
next = 0;
|
|
|
|
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
|
|
|
af6 = af6->ip6af_down) {
|
|
|
|
if (af6->ip6af_off != next) {
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
1999-11-22 02:45:11 +00:00
|
|
|
return IPPROTO_DONE;
|
|
|
|
}
|
|
|
|
next += af6->ip6af_frglen;
|
|
|
|
}
|
|
|
|
if (af6->ip6af_up->ip6af_mff) {
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
1999-11-22 02:45:11 +00:00
|
|
|
return IPPROTO_DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reassembly is complete; concatenate fragments.
|
|
|
|
*/
|
|
|
|
ip6af = q6->ip6q_down;
|
|
|
|
t = m = IP6_REASS_MBUF(ip6af);
|
|
|
|
af6 = ip6af->ip6af_down;
|
2000-07-04 16:35:15 +00:00
|
|
|
frag6_deq(ip6af);
|
1999-11-22 02:45:11 +00:00
|
|
|
while (af6 != (struct ip6asfrag *)q6) {
|
2000-07-04 16:35:15 +00:00
|
|
|
af6dwn = af6->ip6af_down;
|
|
|
|
frag6_deq(af6);
|
1999-11-22 02:45:11 +00:00
|
|
|
while (t->m_next)
|
|
|
|
t = t->m_next;
|
2015-10-27 22:11:09 +00:00
|
|
|
m_adj(IP6_REASS_MBUF(af6), af6->ip6af_offset);
|
|
|
|
m_cat(t, IP6_REASS_MBUF(af6));
|
2000-07-04 16:35:15 +00:00
|
|
|
free(af6, M_FTABLE);
|
|
|
|
af6 = af6dwn;
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* adjust offset to point where the original next header starts */
|
|
|
|
offset = ip6af->ip6af_offset - sizeof(struct ip6_frag);
|
2000-07-04 16:35:15 +00:00
|
|
|
free(ip6af, M_FTABLE);
|
|
|
|
ip6 = mtod(m, struct ip6_hdr *);
|
1999-11-22 02:45:11 +00:00
|
|
|
ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr));
|
2007-06-04 06:06:35 +00:00
|
|
|
if (q6->ip6q_ecn == IPTOS_ECN_CE)
|
|
|
|
ip6->ip6_flow |= htonl(IPTOS_ECN_CE << 20);
|
1999-11-22 02:45:11 +00:00
|
|
|
nxt = q6->ip6q_nxt;
|
2000-07-04 16:35:15 +00:00
|
|
|
#ifdef notyet
|
|
|
|
*q6->ip6q_nxtp = (u_char)(nxt & 0xff);
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
|
2015-02-16 01:12:20 +00:00
|
|
|
if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) {
|
|
|
|
frag6_remque(q6);
|
|
|
|
V_frag6_nfrags -= q6->ip6q_nfrag;
|
2008-10-26 22:45:18 +00:00
|
|
|
#ifdef MAC
|
2015-02-16 01:12:20 +00:00
|
|
|
mac_ip6q_destroy(q6);
|
2008-10-26 22:45:18 +00:00
|
|
|
#endif
|
2015-02-16 01:12:20 +00:00
|
|
|
free(q6, M_FTABLE);
|
|
|
|
V_frag6_nfragpackets--;
|
|
|
|
|
|
|
|
goto dropfrag;
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Store NXT to the original.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
char *prvnxtp = ip6_get_prevhdr(m, offset); /* XXX */
|
|
|
|
*prvnxtp = nxt;
|
|
|
|
}
|
|
|
|
|
|
|
|
frag6_remque(q6);
|
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
|
|
|
V_frag6_nfrags -= q6->ip6q_nfrag;
|
2008-10-26 22:45:18 +00:00
|
|
|
#ifdef MAC
|
|
|
|
mac_ip6q_reassemble(q6, m);
|
|
|
|
mac_ip6q_destroy(q6);
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
free(q6, M_FTABLE);
|
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
|
|
|
V_frag6_nfragpackets--;
|
1999-11-22 02:45:11 +00:00
|
|
|
|
|
|
|
if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */
|
|
|
|
int plen = 0;
|
|
|
|
for (t = m; t; t = t->m_next)
|
|
|
|
plen += t->m_len;
|
|
|
|
m->m_pkthdr.len = plen;
|
|
|
|
}
|
2003-10-07 17:46:18 +00:00
|
|
|
|
2015-11-06 23:07:43 +00:00
|
|
|
#ifdef RSS
|
|
|
|
mtag = m_tag_alloc(MTAG_ABI_IPV6, IPV6_TAG_DIRECT, sizeof(*ip6dc),
|
|
|
|
M_NOWAIT);
|
|
|
|
if (mtag == NULL)
|
|
|
|
goto dropfrag;
|
|
|
|
|
|
|
|
ip6dc = (struct ip6_direct_ctx *)(mtag + 1);
|
|
|
|
ip6dc->ip6dc_nxt = nxt;
|
|
|
|
ip6dc->ip6dc_off = offset;
|
|
|
|
|
|
|
|
m_tag_prepend(m, mtag);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
IP6Q_UNLOCK();
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_reassembled);
|
1999-11-22 02:45:11 +00:00
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_ok);
|
|
|
|
|
2015-11-06 23:07:43 +00:00
|
|
|
#ifdef RSS
|
|
|
|
/*
|
|
|
|
* Queue/dispatch for reprocessing.
|
|
|
|
*/
|
|
|
|
netisr_dispatch(NETISR_IPV6_DIRECT, m);
|
|
|
|
return IPPROTO_DONE;
|
|
|
|
#endif
|
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
/*
|
|
|
|
* Tell launch routine the next header
|
|
|
|
*/
|
|
|
|
|
|
|
|
*mp = m;
|
|
|
|
*offp = offset;
|
|
|
|
|
|
|
|
return nxt;
|
|
|
|
|
|
|
|
dropfrag:
|
2003-10-22 15:32:56 +00:00
|
|
|
IP6Q_UNLOCK();
|
1999-11-22 02:45:11 +00:00
|
|
|
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_fragdropped);
|
1999-11-22 02:45:11 +00:00
|
|
|
m_freem(m);
|
|
|
|
return IPPROTO_DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free a fragment reassembly header and all
|
|
|
|
* associated datagrams.
|
|
|
|
*/
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_freef(struct ip6q *q6)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
|
|
|
struct ip6asfrag *af6, *down6;
|
|
|
|
|
2003-10-22 19:03:49 +00:00
|
|
|
IP6Q_LOCK_ASSERT();
|
2003-10-22 15:29:42 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
|
|
|
af6 = down6) {
|
|
|
|
struct mbuf *m = IP6_REASS_MBUF(af6);
|
|
|
|
|
|
|
|
down6 = af6->ip6af_down;
|
|
|
|
frag6_deq(af6);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return ICMP time exceeded error for the 1st fragment.
|
|
|
|
* Just free other fragments.
|
|
|
|
*/
|
|
|
|
if (af6->ip6af_off == 0) {
|
|
|
|
struct ip6_hdr *ip6;
|
|
|
|
|
|
|
|
/* adjust pointer */
|
|
|
|
ip6 = mtod(m, struct ip6_hdr *);
|
|
|
|
|
2003-10-07 17:46:18 +00:00
|
|
|
/* restore source and destination addresses */
|
1999-11-22 02:45:11 +00:00
|
|
|
ip6->ip6_src = q6->ip6q_src;
|
|
|
|
ip6->ip6_dst = q6->ip6q_dst;
|
|
|
|
|
|
|
|
icmp6_error(m, ICMP6_TIME_EXCEEDED,
|
|
|
|
ICMP6_TIME_EXCEED_REASSEMBLY, 0);
|
2000-07-04 16:35:15 +00:00
|
|
|
} else
|
1999-11-22 02:45:11 +00:00
|
|
|
m_freem(m);
|
2000-07-04 16:35:15 +00:00
|
|
|
free(af6, M_FTABLE);
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
frag6_remque(q6);
|
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
|
|
|
V_frag6_nfrags -= q6->ip6q_nfrag;
|
2008-10-26 22:45:18 +00:00
|
|
|
#ifdef MAC
|
|
|
|
mac_ip6q_destroy(q6);
|
|
|
|
#endif
|
1999-11-22 02:45:11 +00:00
|
|
|
free(q6, M_FTABLE);
|
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
|
|
|
V_frag6_nfragpackets--;
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Put an ip fragment on a reassembly chain.
|
|
|
|
* Like insque, but pointers in middle of structure.
|
|
|
|
*/
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_enq(struct ip6asfrag *af6, struct ip6asfrag *up6)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2003-10-22 19:03:49 +00:00
|
|
|
IP6Q_LOCK_ASSERT();
|
2003-10-22 15:29:42 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
af6->ip6af_up = up6;
|
|
|
|
af6->ip6af_down = up6->ip6af_down;
|
|
|
|
up6->ip6af_down->ip6af_up = af6;
|
|
|
|
up6->ip6af_down = af6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* To frag6_enq as remque is to insque.
|
|
|
|
*/
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_deq(struct ip6asfrag *af6)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2003-10-22 19:03:49 +00:00
|
|
|
IP6Q_LOCK_ASSERT();
|
2003-10-22 15:29:42 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
af6->ip6af_up->ip6af_down = af6->ip6af_down;
|
|
|
|
af6->ip6af_down->ip6af_up = af6->ip6af_up;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_insque(struct ip6q *new, struct ip6q *old)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2003-10-22 19:03:49 +00:00
|
|
|
IP6Q_LOCK_ASSERT();
|
2003-10-22 15:29:42 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
new->ip6q_prev = old;
|
|
|
|
new->ip6q_next = old->ip6q_next;
|
|
|
|
old->ip6q_next->ip6q_prev= new;
|
|
|
|
old->ip6q_next = new;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_remque(struct ip6q *p6)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2003-10-22 19:03:49 +00:00
|
|
|
IP6Q_LOCK_ASSERT();
|
2003-10-22 15:29:42 +00:00
|
|
|
|
1999-11-22 02:45:11 +00:00
|
|
|
p6->ip6q_prev->ip6q_next = p6->ip6q_next;
|
|
|
|
p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-06-11 12:39:29 +00:00
|
|
|
* IPv6 reassembling timer processing;
|
1999-11-22 02:45:11 +00:00
|
|
|
* if a timer expires on a reassembly
|
|
|
|
* queue, discard it.
|
|
|
|
*/
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_slowtimo(void)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
VNET_ITERATOR_DECL(vnet_iter);
|
1999-11-22 02:45:11 +00:00
|
|
|
struct ip6q *q6;
|
|
|
|
|
2009-07-19 14:20:53 +00:00
|
|
|
VNET_LIST_RLOCK_NOSLEEP();
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_LOCK();
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
VNET_FOREACH(vnet_iter) {
|
|
|
|
CURVNET_SET(vnet_iter);
|
|
|
|
q6 = V_ip6q.ip6q_next;
|
|
|
|
if (q6)
|
|
|
|
while (q6 != &V_ip6q) {
|
|
|
|
--q6->ip6q_ttl;
|
|
|
|
q6 = q6->ip6q_next;
|
|
|
|
if (q6->ip6q_prev->ip6q_ttl == 0) {
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_fragtimeout);
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
|
|
|
frag6_freef(q6->ip6q_prev);
|
|
|
|
}
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
/*
|
|
|
|
* If we are over the maximum number of fragments
|
|
|
|
* (due to the limit being lowered), drain off
|
|
|
|
* enough to get down to the new limit.
|
|
|
|
*/
|
|
|
|
while (V_frag6_nfragpackets > (u_int)V_ip6_maxfragpackets &&
|
|
|
|
V_ip6q.ip6q_prev) {
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_fragoverflow);
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
|
|
|
frag6_freef(V_ip6q.ip6q_prev);
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
CURVNET_RESTORE();
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
2009-07-19 14:20:53 +00:00
|
|
|
VNET_LIST_RUNLOCK_NOSLEEP();
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Drain off all datagram fragments.
|
|
|
|
*/
|
|
|
|
void
|
2007-07-05 16:23:49 +00:00
|
|
|
frag6_drain(void)
|
1999-11-22 02:45:11 +00:00
|
|
|
{
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
VNET_ITERATOR_DECL(vnet_iter);
|
2003-10-22 15:29:42 +00:00
|
|
|
|
2009-07-19 14:20:53 +00:00
|
|
|
VNET_LIST_RLOCK_NOSLEEP();
|
|
|
|
if (IP6Q_TRYLOCK() == 0) {
|
|
|
|
VNET_LIST_RUNLOCK_NOSLEEP();
|
1999-11-22 02:45:11 +00:00
|
|
|
return;
|
2009-07-19 14:20:53 +00:00
|
|
|
}
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
VNET_FOREACH(vnet_iter) {
|
|
|
|
CURVNET_SET(vnet_iter);
|
|
|
|
while (V_ip6q.ip6q_next != &V_ip6q) {
|
2013-04-09 07:11:22 +00:00
|
|
|
IP6STAT_INC(ip6s_fragdropped);
|
Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit
Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.
Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().
Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).
All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).
(*) netipsec/keysock.c did not validate depending on compile time options.
Implemented by: julian, bz, brooks, zec
Reviewed by: julian, bz, brooks, kris, rwatson, ...
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
|
|
|
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
|
|
|
frag6_freef(V_ip6q.ip6q_next);
|
|
|
|
}
|
|
|
|
CURVNET_RESTORE();
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
2003-10-22 15:29:42 +00:00
|
|
|
IP6Q_UNLOCK();
|
2009-07-19 14:20:53 +00:00
|
|
|
VNET_LIST_RUNLOCK_NOSLEEP();
|
1999-11-22 02:45:11 +00:00
|
|
|
}
|
2015-02-16 05:58:32 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
|
|
|
|
{
|
|
|
|
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
|
|
|
struct mbuf *t;
|
|
|
|
|
|
|
|
/* Delete frag6 header. */
|
|
|
|
if (m->m_len >= offset + sizeof(struct ip6_frag)) {
|
|
|
|
/* This is the only possible case with !PULLDOWN_TEST. */
|
|
|
|
bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag),
|
|
|
|
offset);
|
|
|
|
m->m_data += sizeof(struct ip6_frag);
|
|
|
|
m->m_len -= sizeof(struct ip6_frag);
|
|
|
|
} else {
|
|
|
|
/* This comes with no copy if the boundary is on cluster. */
|
|
|
|
if ((t = m_split(m, offset, wait)) == NULL)
|
|
|
|
return (ENOMEM);
|
|
|
|
m_adj(t, sizeof(struct ip6_frag));
|
|
|
|
m_cat(m, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|