Merge from vmcontention
This commit is contained in:
commit
a9c72b598a
@ -673,6 +673,10 @@ _install-info= install-info
|
||||
_zoneinfo= zic tzsetup
|
||||
.endif
|
||||
|
||||
.if exists(/usr/sbin/nmtree)
|
||||
_nmtree_itools= nmtree
|
||||
.endif
|
||||
|
||||
ITOOLS= [ awk cap_mkdb cat chflags chmod chown \
|
||||
date echo egrep find grep id install ${_install-info} \
|
||||
ln lockf make mkdir mtree ${_nmtree_itools} mv pwd_mkdb \
|
||||
@ -1134,8 +1138,6 @@ _yacc= usr.bin/yacc
|
||||
.if ${BOOTSTRAPPING} < 1000026
|
||||
_nmtree= lib/libnetbsd \
|
||||
usr.sbin/nmtree
|
||||
.else
|
||||
_nmtree_itools= nmtree
|
||||
.endif
|
||||
|
||||
.if ${BOOTSTRAPPING} < 1000027
|
||||
|
@ -45,6 +45,10 @@ OLD_DIRS+=usr/share/man/man1aout
|
||||
OLD_DIRS+=usr/share/man/cat1aout
|
||||
OLD_DIRS+=usr/share/man/en.ISO8859-1/cat1aout
|
||||
OLD_DIRS+=usr/share/man/en.UTF-8/cat1aout
|
||||
# 20130110: bsd.compat.mk removed
|
||||
OLD_FILES+=usr/share/mk/bsd.compat.mk
|
||||
# 20130103: gnats-supfile removed
|
||||
OLD_FILES+=usr/share/examples/cvsup/gnats-supfile
|
||||
# 20121230: libdisk removed
|
||||
OLD_FILES+=usr/share/man/man3/libdisk.3.gz usr/include/libdisk.h
|
||||
OLD_FILES+=usr/lib/libdisk.a usr/lib32/libdisk.a
|
||||
|
@ -24,10 +24,11 @@
|
||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 26, 2012
|
||||
.Dd February 8, 2012
|
||||
.Dt ZFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -866,7 +867,7 @@ but this may change in future releases). The value
|
||||
disables integrity checking on user data. Disabling checksums is
|
||||
.Em NOT
|
||||
a recommended practice.
|
||||
.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | Cm zle
|
||||
.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | zle | Cm lz4
|
||||
Controls the compression algorithm used for this dataset. The
|
||||
.Cm lzjb
|
||||
compression algorithm is optimized for performance while providing decent data
|
||||
@ -894,6 +895,26 @@ The
|
||||
.Cm zle
|
||||
compression algorithm compresses runs of zeros.
|
||||
.Pp
|
||||
The
|
||||
.Sy lz4
|
||||
compression algorithm is a high-performance replacement
|
||||
for the
|
||||
.Sy lzjb
|
||||
algorithm. It features significantly faster
|
||||
compression and decompression, as well as a moderately higher
|
||||
compression ratio than
|
||||
.Sy lzjb ,
|
||||
but can only be used on pools with
|
||||
the
|
||||
.Sy lz4_compress
|
||||
feature set to
|
||||
.Sy enabled .
|
||||
See
|
||||
.Xr zpool-features 7
|
||||
for details on ZFS feature flags and the
|
||||
.Sy lz4_compress
|
||||
feature.
|
||||
.Pp
|
||||
This property can also be referred to by its shortened column name
|
||||
.Cm compress .
|
||||
Changing this property affects only newly-written data.
|
||||
|
@ -18,10 +18,11 @@
|
||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
.\"
|
||||
.\" Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Aug 28, 2012
|
||||
.Dd February 8, 2012
|
||||
.Dt ZPOOL-FEATURES 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -185,6 +186,49 @@ This feature is
|
||||
.Sy active
|
||||
while there are any filesystems, volumes, or snapshots which were created
|
||||
after enabling this feature.
|
||||
.It Sy lz4_compress
|
||||
.Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress"
|
||||
.It GUID Ta org.illumos:lz4_compress
|
||||
.It READ\-ONLY COMPATIBLE Ta no
|
||||
.It DEPENDENCIES Ta none
|
||||
.El
|
||||
.Pp
|
||||
.Sy lz4
|
||||
is a high-performance real-time compression algorithm that
|
||||
features significantly faster compression and decompression as well as a
|
||||
higher compression ratio than the older
|
||||
.Sy lzjb
|
||||
compression.
|
||||
Typically,
|
||||
.Sy lz4
|
||||
compression is approximately 50% faster on
|
||||
compressible data and 200% faster on incompressible data than
|
||||
.Sy lzjb .
|
||||
It is also approximately 80% faster on decompression, while
|
||||
giving approximately 10% better compression ratio.
|
||||
.Pp
|
||||
When the
|
||||
.Sy lz4_compress
|
||||
feature is set to
|
||||
.Sy enabled ,
|
||||
the
|
||||
administrator can turn on
|
||||
.Sy lz4
|
||||
compression on any dataset on the
|
||||
pool using the
|
||||
.Xr zfs 8
|
||||
command. Please note that doing so will
|
||||
immediately activate the
|
||||
.Sy lz4_compress
|
||||
feature on the underlying
|
||||
pool (even before any data is written). Since this feature is not
|
||||
read-only compatible, this operation will render the pool unimportable
|
||||
on systems without support for the
|
||||
.Sy lz4_compress
|
||||
feature. At the
|
||||
moment, this operation cannot be reversed. Booting off of
|
||||
.Sy lz4
|
||||
-compressed root pools is supported.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr zpool 8
|
||||
|
@ -332,7 +332,7 @@ but is also supported by glibc.
|
||||
The
|
||||
.Fn fmemopen
|
||||
function
|
||||
conforms to
|
||||
conforms to
|
||||
.St -p1003.1-2008 .
|
||||
The ``b'' mode does not conform to any standard
|
||||
but is also supported by glibc.
|
||||
|
@ -98,7 +98,7 @@ If one of
|
||||
or
|
||||
.Dv SF_NOUNLINK
|
||||
is set a non-super-user cannot change any flags and even the super-user
|
||||
can change flags only if securelevel is greater than 0.
|
||||
can change flags only if securelevel is 0.
|
||||
(See
|
||||
.Xr init 8
|
||||
for details.)
|
||||
|
@ -402,7 +402,8 @@ cpu_thread_alloc(struct thread *td)
|
||||
* the ARM EABI.
|
||||
*/
|
||||
td->td_frame = (struct trapframe *)STACKALIGN((u_int)td->td_kstack +
|
||||
USPACE_SVC_STACK_TOP - sizeof(struct pcb) - 1);
|
||||
USPACE_SVC_STACK_TOP - sizeof(struct pcb) -
|
||||
sizeof(struct trapframe));
|
||||
#ifdef __XSCALE__
|
||||
#ifndef CPU_XSCALE_CORE3
|
||||
pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE);
|
||||
|
@ -5,6 +5,7 @@ are used by the ZFS bootstrap:
|
||||
|
||||
fletcher.c checksum support
|
||||
sha256.c checksum support
|
||||
lz4.c compression support
|
||||
lzjb.c compression support
|
||||
zfssubr.c checksum, compression and raidz support
|
||||
zfsimpl.h mostly describing the physical layout
|
||||
|
308
sys/cddl/boot/zfs/lz4.c
Normal file
308
sys/cddl/boot/zfs/lz4.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-2013, Yann Collet.
|
||||
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
* - LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
|
||||
int isize, int maxOutputSize);
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int dummy __unused)
|
||||
{
|
||||
const uint8_t *src = s_start;
|
||||
uint32_t bufsiz = htonl(*(uint32_t *)src);
|
||||
|
||||
/* invalid compressed buffer size encoded at start */
|
||||
if (bufsiz + 4 > s_len)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Returns 0 on success (decompression function returned non-negative)
|
||||
* and non-zero on failure (decompression function returned negative).
|
||||
*/
|
||||
return (LZ4_uncompress_unknownOutputSize(s_start + 4, d_start, bufsiz,
|
||||
d_len) < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU Feature Detection
|
||||
*/
|
||||
|
||||
/* 32 or 64 bits ? */
|
||||
#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || \
|
||||
defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || \
|
||||
defined(__LP64__) || defined(_LP64))
|
||||
#define LZ4_ARCH64 1
|
||||
#else
|
||||
#define LZ4_ARCH64 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Little Endian or Big Endian?
|
||||
* Note: overwrite the below #define if you know your architecture endianess.
|
||||
*/
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define LZ4_BIG_ENDIAN 1
|
||||
#else
|
||||
/*
|
||||
* Little Endian assumed. PDP Endian and other very rare endian format
|
||||
* are unsupported.
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compiler Options
|
||||
*/
|
||||
#if __STDC_VERSION__ >= 199901L /* C99 */
|
||||
/* "restrict" is a known keyword */
|
||||
#else
|
||||
/* Disable restrict */
|
||||
#define restrict
|
||||
#endif
|
||||
|
||||
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
|
||||
#define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) \
|
||||
| (((x) & 0xffu) << 8)))
|
||||
|
||||
#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
#else
|
||||
#define expect(expr, value) (expr)
|
||||
#endif
|
||||
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
|
||||
/* Basic types */
|
||||
#define BYTE uint8_t
|
||||
#define U16 uint16_t
|
||||
#define U32 uint32_t
|
||||
#define S32 int32_t
|
||||
#define U64 uint64_t
|
||||
|
||||
typedef struct _U16_S {
|
||||
U16 v;
|
||||
} U16_S;
|
||||
typedef struct _U32_S {
|
||||
U32 v;
|
||||
} U32_S;
|
||||
typedef struct _U64_S {
|
||||
U64 v;
|
||||
} U64_S;
|
||||
|
||||
#define A64(x) (((U64_S *)(x))->v)
|
||||
#define A32(x) (((U32_S *)(x))->v)
|
||||
#define A16(x) (((U16_S *)(x))->v)
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
#define MINMATCH 4
|
||||
|
||||
#define COPYLENGTH 8
|
||||
#define LASTLITERALS 5
|
||||
|
||||
#define ML_BITS 4
|
||||
#define ML_MASK ((1U<<ML_BITS)-1)
|
||||
#define RUN_BITS (8-ML_BITS)
|
||||
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
||||
|
||||
/*
|
||||
* Architecture-specific macros
|
||||
*/
|
||||
#if LZ4_ARCH64
|
||||
#define STEPSIZE 8
|
||||
#define UARCH U64
|
||||
#define AARCH A64
|
||||
#define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8;
|
||||
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d)
|
||||
#define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e)
|
||||
#define HTYPE U32
|
||||
#define INITBASE(base) const BYTE* const base = ip
|
||||
#else
|
||||
#define STEPSIZE 4
|
||||
#define UARCH U32
|
||||
#define AARCH A32
|
||||
#define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4;
|
||||
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
|
||||
#define LZ4_SECURECOPY LZ4_WILDCOPY
|
||||
#define HTYPE const BYTE*
|
||||
#define INITBASE(base) const int base = 0
|
||||
#endif
|
||||
|
||||
#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
|
||||
{ U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p, i) \
|
||||
{ U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p += 2; }
|
||||
#else
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - A16(p); }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = v; p += 2; }
|
||||
#endif
|
||||
|
||||
/* Macros */
|
||||
#define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
|
||||
|
||||
/* Decompression functions */
|
||||
|
||||
static int
|
||||
LZ4_uncompress_unknownOutputSize(const char *source,
|
||||
char *dest, int isize, int maxOutputSize)
|
||||
{
|
||||
/* Local Variables */
|
||||
const BYTE *restrict ip = (const BYTE *) source;
|
||||
const BYTE *const iend = ip + isize;
|
||||
const BYTE *restrict ref;
|
||||
|
||||
BYTE *restrict op = (BYTE *) dest;
|
||||
BYTE *const oend = op + maxOutputSize;
|
||||
BYTE *cpy;
|
||||
|
||||
size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
|
||||
|
||||
/* Main Loop */
|
||||
while (ip < iend) {
|
||||
BYTE token;
|
||||
int length;
|
||||
|
||||
/* get runlength */
|
||||
token = *ip++;
|
||||
if ((length = (token >> ML_BITS)) == RUN_MASK) {
|
||||
int s = 255;
|
||||
while ((ip < iend) && (s == 255)) {
|
||||
s = *ip++;
|
||||
length += s;
|
||||
}
|
||||
}
|
||||
/* copy literals */
|
||||
cpy = op + length;
|
||||
if ((cpy > oend - COPYLENGTH) ||
|
||||
(ip + length > iend - COPYLENGTH)) {
|
||||
if (cpy > oend)
|
||||
/*
|
||||
* Error: request to write beyond destination
|
||||
* buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
if (ip + length > iend)
|
||||
/*
|
||||
* Error : request to read beyond source
|
||||
* buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
memcpy(op, ip, length);
|
||||
op += length;
|
||||
ip += length;
|
||||
if (ip < iend)
|
||||
/* Error : LZ4 format violation */
|
||||
goto _output_error;
|
||||
/* Necessarily EOF, due to parsing restrictions. */
|
||||
break;
|
||||
}
|
||||
LZ4_WILDCOPY(ip, op, cpy);
|
||||
ip -= (op - cpy);
|
||||
op = cpy;
|
||||
|
||||
/* get offset */
|
||||
LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
|
||||
ip += 2;
|
||||
if (ref < (BYTE * const) dest)
|
||||
/*
|
||||
* Error: offset creates reference outside of
|
||||
* destination buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
|
||||
/* get matchlength */
|
||||
if ((length = (token & ML_MASK)) == ML_MASK) {
|
||||
while (ip < iend) {
|
||||
int s = *ip++;
|
||||
length += s;
|
||||
if (s == 255)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* copy repeated sequence */
|
||||
if unlikely(op - ref < STEPSIZE) {
|
||||
#if LZ4_ARCH64
|
||||
size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
||||
size_t dec2 = dec2table[op - ref];
|
||||
#else
|
||||
const int dec2 = 0;
|
||||
#endif
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
ref -= dec[op - ref];
|
||||
A32(op) = A32(ref);
|
||||
op += STEPSIZE - 4;
|
||||
ref -= dec2;
|
||||
} else {
|
||||
LZ4_COPYSTEP(ref, op);
|
||||
}
|
||||
cpy = op + length - (STEPSIZE - 4);
|
||||
if (cpy > oend - COPYLENGTH) {
|
||||
if (cpy > oend)
|
||||
/*
|
||||
* Error: request to write outside of
|
||||
* destination buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
|
||||
while (op < cpy)
|
||||
*op++ = *ref++;
|
||||
op = cpy;
|
||||
if (op == oend)
|
||||
/*
|
||||
* Check EOF (should never happen, since last
|
||||
* 5 bytes are supposed to be literals).
|
||||
*/
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
LZ4_SECURECOPY(ref, op, cpy);
|
||||
op = cpy; /* correction */
|
||||
}
|
||||
|
||||
/* end of decoding */
|
||||
return (int)(((char *)op) - dest);
|
||||
|
||||
/* write overflow error detected */
|
||||
_output_error:
|
||||
return (int)(-(((char *)ip) - source));
|
||||
}
|
@ -52,6 +52,9 @@
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#define MAXNAMELEN 256
|
||||
|
||||
@ -439,6 +442,7 @@ enum zio_compress {
|
||||
ZIO_COMPRESS_GZIP_8,
|
||||
ZIO_COMPRESS_GZIP_9,
|
||||
ZIO_COMPRESS_ZLE,
|
||||
ZIO_COMPRESS_LZ4,
|
||||
ZIO_COMPRESS_FUNCTIONS
|
||||
};
|
||||
|
||||
|
@ -119,6 +119,7 @@ typedef struct zio_compress_info {
|
||||
|
||||
#include "lzjb.c"
|
||||
#include "zle.c"
|
||||
#include "lz4.c"
|
||||
|
||||
/*
|
||||
* Compression vectors.
|
||||
@ -139,6 +140,7 @@ static zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
|
||||
{NULL, NULL, 8, "gzip-8"},
|
||||
{NULL, NULL, 9, "gzip-9"},
|
||||
{NULL, zle_decompress, 64, "zle"},
|
||||
{NULL, lz4_decompress, 0, "lz4"},
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -42,6 +42,11 @@
|
||||
#ifndef _OPENSOLARIS_SYS_BYTEORDER_H_
|
||||
#define _OPENSOLARIS_SYS_BYTEORDER_H_
|
||||
|
||||
/* for htonl() */
|
||||
#ifndef _KERNEL
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros to reverse byte order
|
||||
*/
|
||||
@ -86,4 +91,6 @@
|
||||
#define ntohll(x) BSWAP_64(x)
|
||||
#endif
|
||||
|
||||
#define BE_IN32(xa) htonl(*((uint32_t *)(void *)(xa)))
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_BYTEORDER_H_ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
@ -155,4 +156,7 @@ zpool_feature_init(void)
|
||||
zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
|
||||
"com.delphix:empty_bpobj", "empty_bpobj",
|
||||
"Snapshots use less space.", B_TRUE, B_FALSE, NULL);
|
||||
zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
|
||||
"org.illumos:lz4_compress", "lz4_compress",
|
||||
"LZ4 compression algorithm support.", B_FALSE, B_FALSE, NULL);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ZFEATURE_COMMON_H
|
||||
@ -51,6 +52,7 @@ typedef int (zfeature_func_t)(zfeature_info_t *fi, void *arg);
|
||||
static enum spa_feature {
|
||||
SPA_FEATURE_ASYNC_DESTROY,
|
||||
SPA_FEATURE_EMPTY_BPOBJ,
|
||||
SPA_FEATURE_LZ4_COMPRESS,
|
||||
SPA_FEATURES
|
||||
} spa_feature_t;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -96,6 +97,7 @@ zfs_prop_init(void)
|
||||
{ "gzip-8", ZIO_COMPRESS_GZIP_8 },
|
||||
{ "gzip-9", ZIO_COMPRESS_GZIP_9 },
|
||||
{ "zle", ZIO_COMPRESS_ZLE },
|
||||
{ "lz4", ZIO_COMPRESS_LZ4 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -211,8 +213,8 @@ zfs_prop_init(void)
|
||||
zprop_register_index(ZFS_PROP_COMPRESSION, "compression",
|
||||
ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
||||
"on | off | lzjb | gzip | gzip-[1-9] | zle", "COMPRESS",
|
||||
compress_table);
|
||||
"on | off | lzjb | gzip | gzip-[1-9] | zle | lz4",
|
||||
"COMPRESS", compress_table);
|
||||
zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
|
||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||
"hidden | visible", "SNAPDIR", snapdir_table);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#
|
||||
# Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
# Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
#
|
||||
#
|
||||
# This Makefile defines all file modules for the directory uts/common
|
||||
@ -56,6 +57,7 @@ ZFS_COMMON_OBJS += \
|
||||
dsl_scan.o \
|
||||
zfeature.o \
|
||||
gzip.o \
|
||||
lz4.o \
|
||||
lzjb.o \
|
||||
metaslab.o \
|
||||
refcount.o \
|
||||
|
@ -0,0 +1,30 @@
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Copyright (C) 2011-2013, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
|
||||
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.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
@ -0,0 +1 @@
|
||||
LZ4 COMPRESSION FUNCTIONALITY IN ZFS
|
1064
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c
Normal file
1064
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ZIO_H
|
||||
@ -106,14 +107,17 @@ enum zio_compress {
|
||||
ZIO_COMPRESS_GZIP_8,
|
||||
ZIO_COMPRESS_GZIP_9,
|
||||
ZIO_COMPRESS_ZLE,
|
||||
ZIO_COMPRESS_LZ4,
|
||||
ZIO_COMPRESS_FUNCTIONS
|
||||
};
|
||||
|
||||
/* N.B. when altering this value, also change BOOTFS_COMPRESS_VALID below */
|
||||
#define ZIO_COMPRESS_ON_VALUE ZIO_COMPRESS_LZJB
|
||||
#define ZIO_COMPRESS_DEFAULT ZIO_COMPRESS_OFF
|
||||
|
||||
#define BOOTFS_COMPRESS_VALID(compress) \
|
||||
((compress) == ZIO_COMPRESS_LZJB || \
|
||||
(compress) == ZIO_COMPRESS_LZ4 || \
|
||||
((compress) == ZIO_COMPRESS_ON && \
|
||||
ZIO_COMPRESS_ON_VALUE == ZIO_COMPRESS_LZJB) || \
|
||||
(compress) == ZIO_COMPRESS_OFF)
|
||||
|
@ -23,6 +23,9 @@
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZIO_COMPRESS_H
|
||||
#define _SYS_ZIO_COMPRESS_H
|
||||
@ -68,6 +71,10 @@ extern size_t zle_compress(void *src, void *dst, size_t s_len, size_t d_len,
|
||||
int level);
|
||||
extern int zle_decompress(void *src, void *dst, size_t s_len, size_t d_len,
|
||||
int level);
|
||||
extern size_t lz4_compress(void *src, void *dst, size_t s_len, size_t d_len,
|
||||
int level);
|
||||
extern int lz4_decompress(void *src, void *dst, size_t s_len, size_t d_len,
|
||||
int level);
|
||||
|
||||
/*
|
||||
* Compress and decompress data if necessary.
|
||||
|
@ -27,6 +27,7 @@
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -75,6 +76,7 @@
|
||||
#include <sys/zvol.h>
|
||||
#include <sys/dsl_scan.h>
|
||||
#include <sys/dmu_objset.h>
|
||||
#include <sys/zfeature.h>
|
||||
|
||||
#include "zfs_namecheck.h"
|
||||
#include "zfs_prop.h"
|
||||
@ -131,6 +133,12 @@ int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t **);
|
||||
|
||||
static void zfsdev_close(void *data);
|
||||
|
||||
static int zfs_prop_activate_feature(dsl_pool_t *dp, zfeature_info_t *feature);
|
||||
static int zfs_prop_activate_feature_check(void *arg1, void *arg2,
|
||||
dmu_tx_t *tx);
|
||||
static void zfs_prop_activate_feature_sync(void *arg1, void *arg2,
|
||||
dmu_tx_t *tx);
|
||||
|
||||
/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
|
||||
void
|
||||
__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
@ -2264,6 +2272,40 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZFS_PROP_COMPRESSION:
|
||||
{
|
||||
if (intval == ZIO_COMPRESS_LZ4) {
|
||||
zfeature_info_t *feature =
|
||||
&spa_feature_table[SPA_FEATURE_LZ4_COMPRESS];
|
||||
spa_t *spa;
|
||||
dsl_pool_t *dp;
|
||||
|
||||
if ((err = spa_open(dsname, &spa, FTAG)) != 0)
|
||||
return (err);
|
||||
|
||||
dp = spa->spa_dsl_pool;
|
||||
|
||||
/*
|
||||
* Setting the LZ4 compression algorithm activates
|
||||
* the feature.
|
||||
*/
|
||||
if (!spa_feature_is_active(spa, feature)) {
|
||||
if ((err = zfs_prop_activate_feature(dp,
|
||||
feature)) != 0) {
|
||||
spa_close(spa, FTAG);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
||||
spa_close(spa, FTAG);
|
||||
}
|
||||
/*
|
||||
* We still want the default set action to be performed in the
|
||||
* caller, we only performed zfeature settings here.
|
||||
*/
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
err = -1;
|
||||
@ -3481,6 +3523,22 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
|
||||
SPA_VERSION_ZLE_COMPRESSION))
|
||||
return (ENOTSUP);
|
||||
|
||||
if (intval == ZIO_COMPRESS_LZ4) {
|
||||
zfeature_info_t *feature =
|
||||
&spa_feature_table[
|
||||
SPA_FEATURE_LZ4_COMPRESS];
|
||||
spa_t *spa;
|
||||
|
||||
if ((err = spa_open(dsname, &spa, FTAG)) != 0)
|
||||
return (err);
|
||||
|
||||
if (!spa_feature_is_enabled(spa, feature)) {
|
||||
spa_close(spa, FTAG);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
spa_close(spa, FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a bootable dataset then
|
||||
* verify that the compression algorithm
|
||||
@ -3524,6 +3582,56 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
|
||||
return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Activates a feature on a pool in response to a property setting. This
|
||||
* creates a new sync task which modifies the pool to reflect the feature
|
||||
* as being active.
|
||||
*/
|
||||
static int
|
||||
zfs_prop_activate_feature(dsl_pool_t *dp, zfeature_info_t *feature)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* EBUSY here indicates that the feature is already active */
|
||||
err = dsl_sync_task_do(dp, zfs_prop_activate_feature_check,
|
||||
zfs_prop_activate_feature_sync, dp->dp_spa, feature, 2);
|
||||
|
||||
if (err != 0 && err != EBUSY)
|
||||
return (err);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks for a race condition to make sure we don't increment a feature flag
|
||||
* multiple times.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
zfs_prop_activate_feature_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
spa_t *spa = arg1;
|
||||
zfeature_info_t *feature = arg2;
|
||||
|
||||
if (!spa_feature_is_active(spa, feature))
|
||||
return (0);
|
||||
else
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
* The callback invoked on feature activation in the sync task caused by
|
||||
* zfs_prop_activate_feature.
|
||||
*/
|
||||
static void
|
||||
zfs_prop_activate_feature_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
spa_t *spa = arg1;
|
||||
zfeature_info_t *feature = arg2;
|
||||
|
||||
spa_feature_incr(spa, feature, tx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes properties from the given props list that fail permission checks
|
||||
* needed to clear them and to restore them in case of a receive error. For each
|
||||
|
@ -23,6 +23,9 @@
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/compress.h>
|
||||
@ -50,6 +53,7 @@ zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
|
||||
{gzip_compress, gzip_decompress, 8, "gzip-8"},
|
||||
{gzip_compress, gzip_decompress, 9, "gzip-9"},
|
||||
{zle_compress, zle_decompress, 64, "zle"},
|
||||
{lz4_compress, lz4_decompress, 0, "lz4"},
|
||||
};
|
||||
|
||||
enum zio_compress
|
||||
|
@ -202,6 +202,7 @@ cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c optional zfs compile-wit
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_synctask.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/gzip.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/lzjb.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c optional zfs compile-with "${ZFS_C}"
|
||||
cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c optional zfs compile-with "${ZFS_C}"
|
||||
|
@ -306,10 +306,14 @@ ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
|
||||
& AR_TxIntrReq;
|
||||
ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
|
||||
ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
|
||||
/* ctl6 - we only need encrtype; the rest are blank */
|
||||
ads->ds_ctl6 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType);
|
||||
#else
|
||||
ads->ds_ctl0 = AR5416DESC_CONST(ds0)->ds_ctl0 & AR_TxIntrReq;
|
||||
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
|
||||
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
|
||||
/* ctl6 - we only need encrtype; the rest are blank */
|
||||
ads->ds_ctl6 = AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType;
|
||||
#endif
|
||||
} else { /* !firstSeg && !lastSeg */
|
||||
/*
|
||||
@ -318,8 +322,10 @@ ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
|
||||
#ifdef AH_NEED_DESC_SWAP
|
||||
ads->ds_ctl0 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl0)
|
||||
& AR_TxIntrReq;
|
||||
ads->ds_ctl6 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType);
|
||||
#else
|
||||
ads->ds_ctl0 = AR5416DESC_CONST(ds0)->ds_ctl0 & AR_TxIntrReq;
|
||||
ads->ds_ctl6 = AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType;
|
||||
#endif
|
||||
ads->ds_ctl1 = segLen | AR_TxMore;
|
||||
ads->ds_ctl2 = 0;
|
||||
|
@ -5161,23 +5161,24 @@ get_sge_context(struct adapter *sc, struct t4_sge_context *cntxt)
|
||||
cntxt->mem_id != CTXT_FLM && cntxt->mem_id != CTXT_CNM)
|
||||
return (EINVAL);
|
||||
|
||||
rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ctxt");
|
||||
if (rc)
|
||||
return (rc);
|
||||
|
||||
if (sc->flags & FW_OK) {
|
||||
rc = begin_synchronized_op(sc, NULL, HOLD_LOCK, "t4ctxt");
|
||||
if (rc == 0) {
|
||||
rc = -t4_sge_ctxt_rd(sc, sc->mbox, cntxt->cid,
|
||||
cntxt->mem_id, &cntxt->data[0]);
|
||||
end_synchronized_op(sc, LOCK_HELD);
|
||||
if (rc == 0)
|
||||
return (0);
|
||||
}
|
||||
rc = -t4_sge_ctxt_rd(sc, sc->mbox, cntxt->cid, cntxt->mem_id,
|
||||
&cntxt->data[0]);
|
||||
if (rc == 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read via firmware failed or wasn't even attempted. Read directly via
|
||||
* the backdoor.
|
||||
*/
|
||||
rc = -t4_sge_ctxt_rd_bd(sc, cntxt->cid, cntxt->mem_id,
|
||||
&cntxt->data[0]);
|
||||
rc = -t4_sge_ctxt_rd_bd(sc, cntxt->cid, cntxt->mem_id, &cntxt->data[0]);
|
||||
done:
|
||||
end_synchronized_op(sc, 0);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
@ -511,10 +511,6 @@ tmpfs_mappedread(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *uio
|
||||
offset = addr & PAGE_MASK;
|
||||
tlen = MIN(PAGE_SIZE - offset, len);
|
||||
|
||||
if ((vobj == NULL) ||
|
||||
(vobj->resident_page_count == 0 && vm_object_cache_is_empty(vobj)))
|
||||
goto nocache;
|
||||
|
||||
VM_OBJECT_LOCK(vobj);
|
||||
lookupvpg:
|
||||
if (((m = vm_page_lookup(vobj, idx)) != NULL) &&
|
||||
@ -569,7 +565,6 @@ tmpfs_mappedread(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *uio
|
||||
return (error);
|
||||
}
|
||||
VM_OBJECT_UNLOCK(vobj);
|
||||
nocache:
|
||||
error = tmpfs_nocacheread(tobj, idx, offset, tlen, uio);
|
||||
|
||||
return (error);
|
||||
@ -639,13 +634,6 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *ui
|
||||
offset = addr & PAGE_MASK;
|
||||
tlen = MIN(PAGE_SIZE - offset, len);
|
||||
|
||||
if ((vobj == NULL) ||
|
||||
(vobj->resident_page_count == 0 &&
|
||||
vm_object_cache_is_empty(vobj))) {
|
||||
vpg = NULL;
|
||||
goto nocache;
|
||||
}
|
||||
|
||||
VM_OBJECT_LOCK(vobj);
|
||||
lookupvpg:
|
||||
if (((vpg = vm_page_lookup(vobj, idx)) != NULL) &&
|
||||
@ -669,7 +657,6 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *ui
|
||||
VM_OBJECT_UNLOCK(vobj);
|
||||
vpg = NULL;
|
||||
}
|
||||
nocache:
|
||||
VM_OBJECT_LOCK(tobj);
|
||||
tpg = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |
|
||||
VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
|
||||
|
@ -33,5 +33,6 @@ KMOD= if_smsc
|
||||
SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \
|
||||
miibus_if.h opt_inet.h opt_platform.h \
|
||||
if_smsc.c
|
||||
SRCS+= ofw_bus_if.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -500,12 +500,12 @@ struct sctp_error_unrecognized_chunk {
|
||||
#define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000
|
||||
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000
|
||||
#define SCTP_PCB_FLAGS_SOCKET_CANT_READ 0x40000000
|
||||
|
||||
/* flags to copy to new PCB */
|
||||
#define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\
|
||||
SCTP_PCB_FLAGS_WAKEINPUT|\
|
||||
SCTP_PCB_FLAGS_BOUND_V6)
|
||||
|
||||
|
||||
/*
|
||||
* PCB Features (in sctp_features bitmask)
|
||||
*/
|
||||
|
@ -1916,7 +1916,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
return;
|
||||
}
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
if (stcb->asoc.local_scope == 0) {
|
||||
if (stcb->asoc.scope.local_scope == 0) {
|
||||
return;
|
||||
}
|
||||
/* is it the right link local scope? */
|
||||
@ -1924,7 +1924,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (stcb->asoc.site_scope == 0 &&
|
||||
if (stcb->asoc.scope.site_scope == 0 &&
|
||||
IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
|
||||
return;
|
||||
}
|
||||
@ -1948,7 +1948,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* we skip unspecifed addresses */
|
||||
return;
|
||||
}
|
||||
if (stcb->asoc.ipv4_local_scope == 0 &&
|
||||
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
return;
|
||||
}
|
||||
@ -2106,7 +2106,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
if (stcb->asoc.local_scope == 0) {
|
||||
if (stcb->asoc.scope.local_scope == 0) {
|
||||
continue;
|
||||
}
|
||||
/* is it the right link local scope? */
|
||||
@ -2135,7 +2135,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* we skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
if (stcb->asoc.ipv4_local_scope == 0 &&
|
||||
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
continue;
|
||||
}
|
||||
@ -2198,13 +2198,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
} else {
|
||||
/* Need to check scopes for this guy */
|
||||
if (sctp_is_address_in_scope(ifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -2437,7 +2431,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
return (NULL);
|
||||
}
|
||||
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
|
||||
if (stcb->asoc.loopback_scope == 0 &&
|
||||
if (stcb->asoc.scope.loopback_scope == 0 &&
|
||||
SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
|
||||
/* Skip if loopback_scope not set */
|
||||
continue;
|
||||
@ -2446,7 +2440,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
switch (sctp_ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (stcb->asoc.ipv4_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
|
||||
@ -2454,7 +2448,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
/* skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
if (stcb->asoc.ipv4_local_scope == 0 &&
|
||||
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
|
||||
continue;
|
||||
|
||||
@ -2473,7 +2467,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (stcb->asoc.ipv6_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv6_addr_legal) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
|
||||
@ -2487,10 +2481,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (stcb->asoc.local_scope == 0 &&
|
||||
if (stcb->asoc.scope.local_scope == 0 &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
continue;
|
||||
if (stcb->asoc.site_scope == 0 &&
|
||||
if (stcb->asoc.scope.site_scope == 0 &&
|
||||
IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
|
||||
continue;
|
||||
|
||||
|
@ -4262,19 +4262,19 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
(asoc->stream_queue_cnt == 0)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
|
||||
goto abort_out_now;
|
||||
}
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
}
|
||||
@ -4973,11 +4973,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
} else {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
@ -4985,6 +4980,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
@ -4996,19 +4996,19 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
(asoc->stream_queue_cnt == 0)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
|
||||
goto abort_out_now;
|
||||
}
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
return;
|
||||
|
@ -956,7 +956,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
} else {
|
||||
/* no outstanding data to send, so move on... */
|
||||
/* send SHUTDOWN-ACK */
|
||||
sctp_send_shutdown_ack(stcb, net);
|
||||
/* move to SHUTDOWN-ACK-SENT state */
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
@ -965,6 +964,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown_ack(stcb, net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
|
||||
stcb, net);
|
||||
}
|
||||
@ -2130,13 +2130,13 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
/* get scope variables out of cookie */
|
||||
asoc->ipv4_local_scope = cookie->ipv4_scope;
|
||||
asoc->site_scope = cookie->site_scope;
|
||||
asoc->local_scope = cookie->local_scope;
|
||||
asoc->loopback_scope = cookie->loopback_scope;
|
||||
asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
|
||||
asoc->scope.site_scope = cookie->site_scope;
|
||||
asoc->scope.local_scope = cookie->local_scope;
|
||||
asoc->scope.loopback_scope = cookie->loopback_scope;
|
||||
|
||||
if ((asoc->ipv4_addr_legal != cookie->ipv4_addr_legal) ||
|
||||
(asoc->ipv6_addr_legal != cookie->ipv6_addr_legal)) {
|
||||
if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
|
||||
(asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
|
||||
struct mbuf *op_err;
|
||||
|
||||
/*
|
||||
|
@ -1863,15 +1863,10 @@ struct sack_track sack_array[256] = {
|
||||
|
||||
int
|
||||
sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
int ipv4_addr_legal,
|
||||
int ipv6_addr_legal,
|
||||
int loopback_scope,
|
||||
int ipv4_local_scope,
|
||||
int local_scope SCTP_UNUSED,/* XXX */
|
||||
int site_scope,
|
||||
struct sctp_scoping *scope,
|
||||
int do_update)
|
||||
{
|
||||
if ((loopback_scope == 0) &&
|
||||
if ((scope->loopback_scope == 0) &&
|
||||
(ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) {
|
||||
/*
|
||||
* skip loopback if not in scope *
|
||||
@ -1881,7 +1876,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
switch (ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (ipv4_addr_legal) {
|
||||
if (scope->ipv4_addr_legal) {
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&ifa->address.sin;
|
||||
@ -1889,7 +1884,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
/* not in scope , unspecified */
|
||||
return (0);
|
||||
}
|
||||
if ((ipv4_local_scope == 0) &&
|
||||
if ((scope->ipv4_local_scope == 0) &&
|
||||
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
|
||||
/* private address not in scope */
|
||||
return (0);
|
||||
@ -1901,7 +1896,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (ipv6_addr_legal) {
|
||||
if (scope->ipv6_addr_legal) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
/*
|
||||
@ -1924,7 +1919,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
|
||||
return (0);
|
||||
}
|
||||
if ((site_scope == 0) &&
|
||||
if ((scope->site_scope == 0) &&
|
||||
(IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
|
||||
return (0);
|
||||
}
|
||||
@ -2063,13 +2058,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
|
||||
continue;
|
||||
}
|
||||
if (sctp_is_address_in_scope(sctp_ifap,
|
||||
scope->ipv4_addr_legal,
|
||||
scope->ipv6_addr_legal,
|
||||
scope->loopback_scope,
|
||||
scope->ipv4_local_scope,
|
||||
scope->local_scope,
|
||||
scope->site_scope, 1) == 0) {
|
||||
if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
@ -2099,12 +2088,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
if (sctp_is_address_in_scope(sctp_ifap,
|
||||
scope->ipv4_addr_legal,
|
||||
scope->ipv6_addr_legal,
|
||||
scope->loopback_scope,
|
||||
scope->ipv4_local_scope,
|
||||
scope->local_scope,
|
||||
scope->site_scope, 0) == 0) {
|
||||
scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
if ((chunk_len != NULL) &&
|
||||
@ -2157,12 +2141,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
if (sctp_is_address_in_scope(laddr->ifa,
|
||||
scope->ipv4_addr_legal,
|
||||
scope->ipv6_addr_legal,
|
||||
scope->loopback_scope,
|
||||
scope->ipv4_local_scope,
|
||||
scope->local_scope,
|
||||
scope->site_scope, 1) == 0) {
|
||||
scope, 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
@ -2182,12 +2161,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
if (sctp_is_address_in_scope(laddr->ifa,
|
||||
scope->ipv4_addr_legal,
|
||||
scope->ipv6_addr_legal,
|
||||
scope->loopback_scope,
|
||||
scope->ipv4_local_scope,
|
||||
scope->local_scope,
|
||||
scope->site_scope, 0) == 0) {
|
||||
scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
if ((chunk_len != NULL) &&
|
||||
@ -2801,13 +2775,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
|
||||
}
|
||||
#endif
|
||||
if (stcb) {
|
||||
if (sctp_is_address_in_scope(ifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (((non_asoc_addr_ok == 0) &&
|
||||
@ -2853,13 +2821,7 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
|
||||
continue;
|
||||
}
|
||||
if (stcb) {
|
||||
if (sctp_is_address_in_scope(ifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (((non_asoc_addr_ok == 0) &&
|
||||
@ -3055,13 +3017,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
if (stcb) {
|
||||
if (sctp_is_address_in_scope(sifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n");
|
||||
sifa = NULL;
|
||||
continue;
|
||||
@ -3108,13 +3064,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (stcb) {
|
||||
if (sctp_is_address_in_scope(sifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
|
||||
sifa = NULL;
|
||||
continue;
|
||||
}
|
||||
@ -3135,12 +3085,12 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
|
||||
}
|
||||
}
|
||||
#ifdef INET
|
||||
if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) {
|
||||
stcb->asoc.ipv4_local_scope = 1;
|
||||
if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
retried = 1;
|
||||
goto again_with_private_addresses_allowed;
|
||||
} else if (retried == 1) {
|
||||
stcb->asoc.ipv4_local_scope = 0;
|
||||
stcb->asoc.scope.ipv4_local_scope = 0;
|
||||
}
|
||||
#endif
|
||||
out:
|
||||
@ -3169,12 +3119,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
|
||||
}
|
||||
if (stcb) {
|
||||
if (sctp_is_address_in_scope(tmp_sifa,
|
||||
stcb->asoc.ipv4_addr_legal,
|
||||
stcb->asoc.ipv6_addr_legal,
|
||||
stcb->asoc.loopback_scope,
|
||||
stcb->asoc.ipv4_local_scope,
|
||||
stcb->asoc.local_scope,
|
||||
stcb->asoc.site_scope, 0) == 0) {
|
||||
&stcb->asoc.scope, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (((non_asoc_addr_ok == 0) &&
|
||||
@ -4595,7 +4540,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct sctp_scoping scp;
|
||||
struct mbuf *m;
|
||||
struct sctp_nets *net;
|
||||
struct sctp_init_chunk *init;
|
||||
@ -4675,37 +4619,29 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
|
||||
init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
|
||||
init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
/* now the address restriction */
|
||||
/* XXX Should we take the address family of the socket into account? */
|
||||
sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len);
|
||||
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
|
||||
#ifdef INET6
|
||||
#ifdef INET
|
||||
/* we support 2 types: IPv4/IPv6 */
|
||||
parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + 2 * sizeof(uint16_t));
|
||||
sup_addr->ph.param_length = htons(parameter_len);
|
||||
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
|
||||
sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS);
|
||||
padding_len = 0;
|
||||
#else
|
||||
/* we support 1 type: IPv6 */
|
||||
parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
|
||||
sup_addr->ph.param_length = htons(parameter_len);
|
||||
sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS);
|
||||
sup_addr->addr_type[1] = htons(0); /* this is the padding */
|
||||
padding_len = (uint16_t) sizeof(uint16_t);
|
||||
#endif
|
||||
#else
|
||||
/* we support 1 type: IPv4 */
|
||||
parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
|
||||
sup_addr->ph.param_length = htons(parameter_len);
|
||||
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
|
||||
sup_addr->addr_type[1] = htons(0); /* this is the padding */
|
||||
padding_len = (uint16_t) sizeof(uint16_t);
|
||||
#endif
|
||||
chunk_len += parameter_len;
|
||||
#endif
|
||||
if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
|
||||
uint8_t i;
|
||||
|
||||
parameter_len = (uint16_t) sizeof(struct sctp_paramhdr);
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
parameter_len += (uint16_t) sizeof(uint16_t);
|
||||
}
|
||||
if (stcb->asoc.scope.ipv6_addr_legal) {
|
||||
parameter_len += (uint16_t) sizeof(uint16_t);
|
||||
}
|
||||
sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len);
|
||||
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
|
||||
sup_addr->ph.param_length = htons(parameter_len);
|
||||
i = 0;
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
|
||||
}
|
||||
if (stcb->asoc.scope.ipv6_addr_legal) {
|
||||
sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
|
||||
}
|
||||
padding_len = 4 - 2 * i;
|
||||
chunk_len += parameter_len;
|
||||
}
|
||||
/* Adaptation layer indication parameter */
|
||||
/* XXX: Should we include this always? */
|
||||
if (padding_len > 0) {
|
||||
@ -4860,13 +4796,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
|
||||
* we could just sifa in the address within the stcb. But for now
|
||||
* this is a quick hack to get the address stuff teased apart.
|
||||
*/
|
||||
scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal;
|
||||
scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal;
|
||||
scp.loopback_scope = stcb->asoc.loopback_scope;
|
||||
scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope;
|
||||
scp.local_scope = stcb->asoc.local_scope;
|
||||
scp.site_scope = stcb->asoc.site_scope;
|
||||
sctp_add_addresses_to_i_ia(inp, stcb, &scp, m, cnt_inits_to, &padding_len, &chunk_len);
|
||||
sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len);
|
||||
|
||||
init->ch.chunk_length = htons(chunk_len);
|
||||
if (padding_len > 0) {
|
||||
@ -5507,24 +5437,16 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
*/
|
||||
stc.site_scope = stc.local_scope = stc.loopback_scope = 0;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
struct inpcb *in_inp;
|
||||
|
||||
/* Its a V6 socket */
|
||||
in_inp = (struct inpcb *)inp;
|
||||
stc.ipv6_addr_legal = 1;
|
||||
/* Now look at the binding flag to see if V4 will be legal */
|
||||
if (SCTP_IPV6_V6ONLY(in_inp) == 0) {
|
||||
stc.ipv4_addr_legal = 1;
|
||||
} else {
|
||||
/* V4 addresses are NOT legal on the association */
|
||||
if (SCTP_IPV6_V6ONLY(inp)) {
|
||||
stc.ipv4_addr_legal = 0;
|
||||
} else {
|
||||
stc.ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
/* Its a V4 socket, no - V6 */
|
||||
stc.ipv4_addr_legal = 1;
|
||||
stc.ipv6_addr_legal = 0;
|
||||
stc.ipv4_addr_legal = 1;
|
||||
}
|
||||
|
||||
#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
|
||||
stc.ipv4_scope = 1;
|
||||
#else
|
||||
@ -5629,10 +5551,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
|
||||
#endif
|
||||
|
||||
stc.loopback_scope = asoc->loopback_scope;
|
||||
stc.ipv4_scope = asoc->ipv4_local_scope;
|
||||
stc.site_scope = asoc->site_scope;
|
||||
stc.local_scope = asoc->local_scope;
|
||||
stc.loopback_scope = asoc->scope.loopback_scope;
|
||||
stc.ipv4_scope = asoc->scope.ipv4_local_scope;
|
||||
stc.site_scope = asoc->scope.site_scope;
|
||||
stc.local_scope = asoc->scope.local_scope;
|
||||
#ifdef INET6
|
||||
/* Why do we not consider IPv4 LL addresses? */
|
||||
TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
|
||||
@ -6574,12 +6496,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
* only send SHUTDOWN the first time
|
||||
* through
|
||||
*/
|
||||
sctp_send_shutdown(stcb, net);
|
||||
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown(stcb, net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
|
||||
net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
|
||||
@ -13092,18 +13015,19 @@ sctp_lower_sosend(struct socket *so,
|
||||
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
/* only send SHUTDOWN the first time through */
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
|
||||
netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
|
||||
|
@ -55,13 +55,9 @@ int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
|
||||
|
||||
int
|
||||
sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
int ipv4_addr_legal,
|
||||
int ipv6_addr_legal,
|
||||
int loopback_scope,
|
||||
int ipv4_local_scope,
|
||||
int local_scope,
|
||||
int site_scope,
|
||||
struct sctp_scoping *scope,
|
||||
int do_update);
|
||||
|
||||
int
|
||||
sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa);
|
||||
|
||||
|
@ -94,11 +94,10 @@ sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
|
||||
spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq);
|
||||
spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq);
|
||||
spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks);
|
||||
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Addresses are added to VRF's (Virtual Router's). For BSD we
|
||||
* have only the default VRF 0. We maintain a hash list of
|
||||
* VRF's. Each VRF has its own list of sctp_ifn's. Each of
|
||||
@ -214,7 +213,6 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index)
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct sctp_vrf *
|
||||
sctp_find_vrf(uint32_t vrf_id)
|
||||
{
|
||||
@ -230,6 +228,7 @@ sctp_find_vrf(uint32_t vrf_id)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_free_vrf(struct sctp_vrf *vrf)
|
||||
{
|
||||
@ -245,6 +244,7 @@ sctp_free_vrf(struct sctp_vrf *vrf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
|
||||
{
|
||||
@ -258,6 +258,7 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
|
||||
{
|
||||
@ -283,6 +284,7 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
|
||||
{
|
||||
@ -305,12 +307,13 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
|
||||
sctp_free_ifn(sctp_ifnp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
|
||||
const char *if_name, uint32_t ifn_index)
|
||||
{
|
||||
struct sctp_vrf *vrf;
|
||||
struct sctp_ifa *sctp_ifap = NULL;
|
||||
struct sctp_ifa *sctp_ifap;
|
||||
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
@ -348,12 +351,13 @@ sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
|
||||
const char *if_name, uint32_t ifn_index)
|
||||
{
|
||||
struct sctp_vrf *vrf;
|
||||
struct sctp_ifa *sctp_ifap = NULL;
|
||||
struct sctp_ifa *sctp_ifap;
|
||||
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
@ -391,6 +395,7 @@ sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* Add an ifa to an ifn.
|
||||
* Register the interface as necessary.
|
||||
@ -428,6 +433,7 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* Remove an ifa from its ifn.
|
||||
* If no more addresses exist, remove the ifn too. Otherwise, re-register
|
||||
@ -479,6 +485,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct sctp_ifa *
|
||||
sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
uint32_t ifn_type, const char *if_name, void *ifa,
|
||||
@ -1027,6 +1034,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
{
|
||||
@ -1036,19 +1044,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
struct sctp_ifn *sctp_ifn;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
|
||||
loopback_scope = stcb->asoc.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.local_scope;
|
||||
site_scope = stcb->asoc.site_scope;
|
||||
ipv4_addr_legal = ipv6_addr_legal = 0;
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(stcb->asoc.vrf_id);
|
||||
@ -1183,6 +1184,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rules for use
|
||||
*
|
||||
@ -1471,11 +1473,11 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an association for a specific endpoint using the association id given
|
||||
* out in the COMM_UP notification
|
||||
*/
|
||||
|
||||
struct sctp_tcb *
|
||||
sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
|
||||
{
|
||||
@ -1536,6 +1538,9 @@ sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Endpoint probe expects that the INP_INFO is locked.
|
||||
*/
|
||||
static struct sctp_inpcb *
|
||||
sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
|
||||
uint16_t lport, uint32_t vrf_id)
|
||||
@ -1552,12 +1557,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
|
||||
struct sockaddr_in6 *intf_addr6;
|
||||
|
||||
#endif
|
||||
|
||||
int fnd;
|
||||
|
||||
/*
|
||||
* Endpoint probe expects that the INP_INFO is locked.
|
||||
*/
|
||||
#ifdef INET
|
||||
sin = NULL;
|
||||
#endif
|
||||
@ -1893,6 +1894,7 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
|
||||
return (inp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an association for an endpoint with the pointer to whom you want to
|
||||
* send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
|
||||
@ -2144,6 +2146,7 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an association with the pointer to the inbound IP packet. This can be
|
||||
* a IPv4 or IPv6 packet.
|
||||
@ -3332,22 +3335,23 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
(SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->asoc.alternate) {
|
||||
netp = asoc->asoc.alternate;
|
||||
} else {
|
||||
netp = asoc->asoc.primary_destination;
|
||||
}
|
||||
/*
|
||||
* there is nothing queued to send,
|
||||
* so I send shutdown
|
||||
*/
|
||||
sctp_send_shutdown(asoc, netp);
|
||||
if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(asoc);
|
||||
if (asoc->asoc.alternate) {
|
||||
netp = asoc->asoc.alternate;
|
||||
} else {
|
||||
netp = asoc->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(asoc, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
|
||||
netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
|
||||
@ -3742,13 +3746,13 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
stcb->ipv4_local_scope = 1;
|
||||
#else
|
||||
if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
stcb->asoc.ipv4_local_scope = 1;
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
}
|
||||
#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
|
||||
} else {
|
||||
/* Validate the address is in scope */
|
||||
if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
|
||||
(stcb->asoc.ipv4_local_scope == 0)) {
|
||||
(stcb->asoc.scope.ipv4_local_scope == 0)) {
|
||||
addr_inscope = 0;
|
||||
}
|
||||
}
|
||||
@ -3769,10 +3773,10 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
||||
if (set_scope) {
|
||||
if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
|
||||
stcb->asoc.loopback_scope = 1;
|
||||
stcb->asoc.local_scope = 0;
|
||||
stcb->asoc.ipv4_local_scope = 1;
|
||||
stcb->asoc.site_scope = 1;
|
||||
stcb->asoc.scope.loopback_scope = 1;
|
||||
stcb->asoc.scope.local_scope = 0;
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
stcb->asoc.scope.site_scope = 1;
|
||||
} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
/*
|
||||
* If the new destination is a
|
||||
@ -3784,26 +3788,26 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
* also be on our private network
|
||||
* for v4 too.
|
||||
*/
|
||||
stcb->asoc.ipv4_local_scope = 1;
|
||||
stcb->asoc.site_scope = 1;
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
stcb->asoc.scope.site_scope = 1;
|
||||
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
|
||||
/*
|
||||
* If the new destination is
|
||||
* SITE_LOCAL then we must have site
|
||||
* scope in common.
|
||||
*/
|
||||
stcb->asoc.site_scope = 1;
|
||||
stcb->asoc.scope.site_scope = 1;
|
||||
}
|
||||
} else {
|
||||
/* Validate the address is in scope */
|
||||
if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
|
||||
(stcb->asoc.loopback_scope == 0)) {
|
||||
(stcb->asoc.scope.loopback_scope == 0)) {
|
||||
addr_inscope = 0;
|
||||
} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
|
||||
(stcb->asoc.local_scope == 0)) {
|
||||
(stcb->asoc.scope.local_scope == 0)) {
|
||||
addr_inscope = 0;
|
||||
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
|
||||
(stcb->asoc.site_scope == 0)) {
|
||||
(stcb->asoc.scope.site_scope == 0)) {
|
||||
addr_inscope = 0;
|
||||
}
|
||||
}
|
||||
@ -3838,10 +3842,10 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
}
|
||||
net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
|
||||
if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
|
||||
stcb->asoc.loopback_scope = 1;
|
||||
stcb->asoc.ipv4_local_scope = 1;
|
||||
stcb->asoc.local_scope = 0;
|
||||
stcb->asoc.site_scope = 1;
|
||||
stcb->asoc.scope.loopback_scope = 1;
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
stcb->asoc.scope.local_scope = 0;
|
||||
stcb->asoc.scope.site_scope = 1;
|
||||
addr_inscope = 1;
|
||||
}
|
||||
net->failure_threshold = stcb->asoc.def_net_failure;
|
||||
@ -6070,7 +6074,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
switch (sa->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (stcb->asoc.ipv4_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
|
||||
return (-1);
|
||||
}
|
||||
@ -6079,7 +6083,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (stcb->asoc.ipv6_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv6_addr_legal) {
|
||||
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
|
||||
return (-2);
|
||||
}
|
||||
@ -6126,7 +6130,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
#ifdef INET
|
||||
if (ptype == SCTP_IPV4_ADDRESS) {
|
||||
if (stcb->asoc.ipv4_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
struct sctp_ipv4addr_param *p4, p4_buf;
|
||||
|
||||
/* ok get the v4 address and check/add */
|
||||
@ -6212,7 +6216,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (ptype == SCTP_IPV6_ADDRESS) {
|
||||
if (stcb->asoc.ipv6_addr_legal) {
|
||||
if (stcb->asoc.scope.ipv6_addr_legal) {
|
||||
/* ok get the v6 address and check/add */
|
||||
struct sctp_ipv6addr_param *p6, p6_buf;
|
||||
|
||||
|
@ -1177,17 +1177,7 @@ struct sctp_association {
|
||||
*/
|
||||
uint8_t peer_supports_pktdrop;
|
||||
|
||||
/* Do we allow V6/V4? */
|
||||
uint8_t ipv4_addr_legal;
|
||||
uint8_t ipv6_addr_legal;
|
||||
/* Address scoping flags */
|
||||
/* scope value for IPv4 */
|
||||
uint8_t ipv4_local_scope;
|
||||
/* scope values for IPv6 */
|
||||
uint8_t local_scope;
|
||||
uint8_t site_scope;
|
||||
/* loopback scope */
|
||||
uint8_t loopback_scope;
|
||||
struct sctp_scoping scope;
|
||||
/* flags to handle send alternate net tracking */
|
||||
uint8_t used_alt_onsack;
|
||||
uint8_t used_alt_asconfack;
|
||||
|
@ -197,29 +197,29 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
|
||||
/* Turn on all the appropriate scope */
|
||||
if (stcb) {
|
||||
/* use association specific values */
|
||||
loopback_scope = stcb->asoc.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.local_scope;
|
||||
site_scope = stcb->asoc.site_scope;
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
} else {
|
||||
/* use generic values for endpoints */
|
||||
/* Use generic values for endpoints. */
|
||||
loopback_scope = 1;
|
||||
ipv4_local_scope = 1;
|
||||
local_scope = 1;
|
||||
site_scope = 1;
|
||||
}
|
||||
|
||||
/* use only address families of interest */
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(inp)) {
|
||||
ipv4_addr_legal = 0;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(inp)) {
|
||||
ipv4_addr_legal = 0;
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv6_addr_legal = 0;
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
ipv6_addr_legal = 0;
|
||||
}
|
||||
|
||||
/* neither Mac OS X nor FreeBSD support mulitple routing functions */
|
||||
|
@ -1560,18 +1560,19 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
|
||||
/* only send SHUTDOWN 1st time thru */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
|
||||
stcb->sctp_ep, stcb,
|
||||
netp);
|
||||
|
@ -794,25 +794,24 @@ sctp_disconnect(struct socket *so)
|
||||
/* only send SHUTDOWN 1st time thru */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -1014,24 +1013,24 @@ sctp_shutdown(struct socket *so)
|
||||
/* only send SHUTDOWN the first time through */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -1144,23 +1143,29 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
|
||||
|
||||
if (stcb) {
|
||||
/* Turn on all the appropriate scope */
|
||||
loopback_scope = stcb->asoc.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.local_scope;
|
||||
site_scope = stcb->asoc.site_scope;
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
} else {
|
||||
/* Turn on ALL scope, since we look at the EP */
|
||||
loopback_scope = ipv4_local_scope = local_scope =
|
||||
site_scope = 1;
|
||||
}
|
||||
ipv4_addr_legal = ipv6_addr_legal = 0;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(inp) == 0) {
|
||||
/* Use generic values for endpoints. */
|
||||
loopback_scope = 1;
|
||||
ipv4_local_scope = 1;
|
||||
local_scope = 1;
|
||||
site_scope = 1;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(inp)) {
|
||||
ipv4_addr_legal = 0;
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv6_addr_legal = 0;
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
@ -1299,8 +1304,21 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
|
||||
}
|
||||
if (sctp_fill_user_address(sas, &laddr->ifa->address.sa))
|
||||
continue;
|
||||
|
||||
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
|
||||
switch (laddr->ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* TSNH */
|
||||
break;
|
||||
}
|
||||
sas = (struct sockaddr_storage *)((caddr_t)sas +
|
||||
laddr->ifa->address.sa.sa_len);
|
||||
actual += laddr->ifa->address.sa.sa_len;
|
||||
@ -5949,7 +5967,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
error = EINVAL;
|
||||
goto out_now;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
#endif
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
|
||||
SCTP_PCB_FLAGS_UNBOUND) {
|
||||
/* Bind a ephemeral port */
|
||||
@ -6243,8 +6261,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
|
||||
return (ENOMEM);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
|
||||
sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
|
||||
sin->sin_port = store.sin.sin_port;
|
||||
sin->sin_addr = store.sin.sin_addr;
|
||||
*addr = (struct sockaddr *)sin;
|
||||
break;
|
||||
}
|
||||
@ -6259,9 +6277,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
|
||||
return (ENOMEM);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
|
||||
|
||||
sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
|
||||
sin6->sin6_port = store.sin6.sin6_port;
|
||||
sin6->sin6_addr = store.sin6.sin6_addr;
|
||||
if ((error = sa6_recoverscope(sin6)) != 0) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
return (error);
|
||||
|
@ -878,7 +878,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int ch
|
||||
}
|
||||
|
||||
int
|
||||
sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
uint32_t override_tag, uint32_t vrf_id)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
@ -899,23 +899,23 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
asoc = &stcb->asoc;
|
||||
/* init all variables to a known value. */
|
||||
SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE);
|
||||
asoc->max_burst = m->sctp_ep.max_burst;
|
||||
asoc->fr_max_burst = m->sctp_ep.fr_max_burst;
|
||||
asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||
asoc->cookie_life = m->sctp_ep.def_cookie_life;
|
||||
asoc->sctp_cmt_on_off = m->sctp_cmt_on_off;
|
||||
asoc->ecn_allowed = m->sctp_ecn_enable;
|
||||
asoc->max_burst = inp->sctp_ep.max_burst;
|
||||
asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
|
||||
asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
|
||||
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
asoc->ecn_allowed = inp->sctp_ecn_enable;
|
||||
asoc->sctp_nr_sack_on_off = (uint8_t) SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
|
||||
asoc->sctp_cmt_pf = (uint8_t) 0;
|
||||
asoc->sctp_frag_point = m->sctp_frag_point;
|
||||
asoc->sctp_features = m->sctp_features;
|
||||
asoc->default_dscp = m->sctp_ep.default_dscp;
|
||||
asoc->sctp_frag_point = inp->sctp_frag_point;
|
||||
asoc->sctp_features = inp->sctp_features;
|
||||
asoc->default_dscp = inp->sctp_ep.default_dscp;
|
||||
#ifdef INET6
|
||||
if (m->sctp_ep.default_flowlabel) {
|
||||
asoc->default_flowlabel = m->sctp_ep.default_flowlabel;
|
||||
if (inp->sctp_ep.default_flowlabel) {
|
||||
asoc->default_flowlabel = inp->sctp_ep.default_flowlabel;
|
||||
} else {
|
||||
if (m->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
|
||||
asoc->default_flowlabel = sctp_select_initial_TSN(&m->sctp_ep);
|
||||
if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
|
||||
asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep);
|
||||
asoc->default_flowlabel &= 0x000fffff;
|
||||
asoc->default_flowlabel |= 0x80000000;
|
||||
} else {
|
||||
@ -927,11 +927,11 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
if (override_tag) {
|
||||
asoc->my_vtag = override_tag;
|
||||
} else {
|
||||
asoc->my_vtag = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
|
||||
asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
|
||||
}
|
||||
/* Get the nonce tags */
|
||||
asoc->my_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
|
||||
asoc->peer_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
|
||||
asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
|
||||
asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
|
||||
asoc->vrf_id = vrf_id;
|
||||
|
||||
#ifdef SCTP_ASOCLOG_OF_TSNS
|
||||
@ -948,7 +948,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
asoc->refcnt = 0;
|
||||
asoc->assoc_up_sent = 0;
|
||||
asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
|
||||
sctp_select_initial_TSN(&m->sctp_ep);
|
||||
sctp_select_initial_TSN(&inp->sctp_ep);
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
/* we are optimisitic here */
|
||||
asoc->peer_supports_pktdrop = 1;
|
||||
@ -966,49 +966,42 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
/* here we are different, we hold the next one we expect */
|
||||
asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
|
||||
|
||||
asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
|
||||
asoc->initial_rto = m->sctp_ep.initial_rto;
|
||||
asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max;
|
||||
asoc->initial_rto = inp->sctp_ep.initial_rto;
|
||||
|
||||
asoc->max_init_times = m->sctp_ep.max_init_times;
|
||||
asoc->max_send_times = m->sctp_ep.max_send_times;
|
||||
asoc->def_net_failure = m->sctp_ep.def_net_failure;
|
||||
asoc->def_net_pf_threshold = m->sctp_ep.def_net_pf_threshold;
|
||||
asoc->max_init_times = inp->sctp_ep.max_init_times;
|
||||
asoc->max_send_times = inp->sctp_ep.max_send_times;
|
||||
asoc->def_net_failure = inp->sctp_ep.def_net_failure;
|
||||
asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold;
|
||||
asoc->free_chunk_cnt = 0;
|
||||
|
||||
asoc->iam_blocking = 0;
|
||||
asoc->context = m->sctp_context;
|
||||
asoc->local_strreset_support = m->local_strreset_support;
|
||||
asoc->def_send = m->def_send;
|
||||
asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
||||
asoc->sack_freq = m->sctp_ep.sctp_sack_freq;
|
||||
asoc->context = inp->sctp_context;
|
||||
asoc->local_strreset_support = inp->local_strreset_support;
|
||||
asoc->def_send = inp->def_send;
|
||||
asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
||||
asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
|
||||
asoc->pr_sctp_cnt = 0;
|
||||
asoc->total_output_queue_size = 0;
|
||||
|
||||
if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
struct in6pcb *inp6;
|
||||
|
||||
/* Its a V6 socket */
|
||||
inp6 = (struct in6pcb *)m;
|
||||
asoc->ipv6_addr_legal = 1;
|
||||
/* Now look at the binding flag to see if V4 will be legal */
|
||||
if (SCTP_IPV6_V6ONLY(inp6) == 0) {
|
||||
asoc->ipv4_addr_legal = 1;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
asoc->scope.ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(inp) == 0) {
|
||||
asoc->scope.ipv4_addr_legal = 1;
|
||||
} else {
|
||||
/* V4 addresses are NOT legal on the association */
|
||||
asoc->ipv4_addr_legal = 0;
|
||||
asoc->scope.ipv4_addr_legal = 0;
|
||||
}
|
||||
} else {
|
||||
/* Its a V4 socket, no - V6 */
|
||||
asoc->ipv4_addr_legal = 1;
|
||||
asoc->ipv6_addr_legal = 0;
|
||||
asoc->scope.ipv6_addr_legal = 0;
|
||||
asoc->scope.ipv4_addr_legal = 1;
|
||||
}
|
||||
|
||||
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(m->sctp_socket), SCTP_MINIMAL_RWND);
|
||||
asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(m->sctp_socket);
|
||||
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND);
|
||||
asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket);
|
||||
|
||||
asoc->smallest_mtu = m->sctp_frag_point;
|
||||
asoc->minrto = m->sctp_ep.sctp_minrto;
|
||||
asoc->maxrto = m->sctp_ep.sctp_maxrto;
|
||||
asoc->smallest_mtu = inp->sctp_frag_point;
|
||||
asoc->minrto = inp->sctp_ep.sctp_minrto;
|
||||
asoc->maxrto = inp->sctp_ep.sctp_maxrto;
|
||||
|
||||
asoc->locked_on_sending = NULL;
|
||||
asoc->stream_locked_on = 0;
|
||||
@ -1025,20 +1018,20 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
/* Setup to fill the hb random cache at first HB */
|
||||
asoc->hb_random_idx = 4;
|
||||
|
||||
asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
|
||||
asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time;
|
||||
|
||||
stcb->asoc.congestion_control_module = m->sctp_ep.sctp_default_cc_module;
|
||||
stcb->asoc.cc_functions = sctp_cc_functions[m->sctp_ep.sctp_default_cc_module];
|
||||
stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module;
|
||||
stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module];
|
||||
|
||||
stcb->asoc.stream_scheduling_module = m->sctp_ep.sctp_default_ss_module;
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[m->sctp_ep.sctp_default_ss_module];
|
||||
stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module;
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module];
|
||||
|
||||
/*
|
||||
* Now the stream parameters, here we allocate space for all streams
|
||||
* that we request by default.
|
||||
*/
|
||||
asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
|
||||
m->sctp_ep.pre_open_stream_count;
|
||||
inp->sctp_ep.pre_open_stream_count;
|
||||
SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
|
||||
asoc->streamoutcnt * sizeof(struct sctp_stream_out),
|
||||
SCTP_M_STRMO);
|
||||
@ -1093,7 +1086,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
TAILQ_INIT(&asoc->sent_queue);
|
||||
TAILQ_INIT(&asoc->reasmqueue);
|
||||
TAILQ_INIT(&asoc->resetHead);
|
||||
asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
|
||||
asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome;
|
||||
TAILQ_INIT(&asoc->asconf_queue);
|
||||
/* authentication fields */
|
||||
asoc->authinfo.random = NULL;
|
||||
@ -1104,7 +1097,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
asoc->authinfo.recv_keyid = 0;
|
||||
LIST_INIT(&asoc->shared_keys);
|
||||
asoc->marked_retrans = 0;
|
||||
asoc->port = m->sctp_ep.port;
|
||||
asoc->port = inp->sctp_ep.port;
|
||||
asoc->timoinit = 0;
|
||||
asoc->timodata = 0;
|
||||
asoc->timosack = 0;
|
||||
@ -6621,20 +6614,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
|
||||
int count = 0;
|
||||
|
||||
/* Turn on all the appropriate scopes */
|
||||
loopback_scope = stcb->asoc.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.local_scope;
|
||||
site_scope = stcb->asoc.site_scope;
|
||||
ipv4_addr_legal = ipv6_addr_legal = 0;
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
ipv6_addr_legal = 1;
|
||||
if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(stcb->asoc.vrf_id);
|
||||
if (vrf == NULL) {
|
||||
|
@ -936,16 +936,16 @@ mlx4_en_transmit_locked(struct ifnet *dev, int tx_ind, struct mbuf *m)
|
||||
return (err);
|
||||
}
|
||||
/* Process the queue */
|
||||
while ((next = drbr_peek(ifp, ring->br)) != NULL) {
|
||||
while ((next = drbr_peek(dev, ring->br)) != NULL) {
|
||||
if ((err = mlx4_en_xmit(dev, tx_ind, &next)) != 0) {
|
||||
if (next == NULL) {
|
||||
drbr_advance(ifp, ring->br);
|
||||
drbr_advance(dev, ring->br);
|
||||
} else {
|
||||
drbr_putback(ifp, ring->br, next);
|
||||
drbr_putback(dev, ring->br, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
drbr_advance(ifp, ring->br);
|
||||
drbr_advance(dev, ring->br);
|
||||
enqueued++;
|
||||
dev->if_obytes += next->m_pkthdr.len;
|
||||
if (next->m_flags & M_MCAST)
|
||||
|
@ -37,6 +37,7 @@ SUBDIR= alias \
|
||||
ctlstat \
|
||||
cut \
|
||||
dirname \
|
||||
dtc \
|
||||
du \
|
||||
ee \
|
||||
elf2aout \
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\" $Id: cvsup.1,v 1.70 2003/03/04 18:23:46 jdp Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 1, 2006
|
||||
.Dd Feburary 8, 2013
|
||||
.Dt CSUP 1
|
||||
.Os FreeBSD
|
||||
.Sh NAME
|
||||
@ -902,14 +902,14 @@ will work through any firewall which permits outbound connections to
|
||||
port 5999 of the server host.
|
||||
.Sh USING csup WITH SOCKS
|
||||
.Nm
|
||||
can be used through a SOCKS proxy server with the standard
|
||||
.Nm runsocks
|
||||
can be used through a SOCKS proxy server with the
|
||||
.Nm tsocks
|
||||
command.
|
||||
Your
|
||||
The
|
||||
.Nm
|
||||
executable needs to be dynamically-linked with the system
|
||||
libraries for
|
||||
.Nm runsocks
|
||||
.Nm tsocks
|
||||
to work properly.
|
||||
.Sh USING ssh PORT FORWARDING
|
||||
As an alternative to SOCKS, a user behind a firewall can penetrate it
|
||||
|
@ -16,7 +16,7 @@ WARNS?= 2
|
||||
NLS= C fr_FR.ISO8859-1 de_DE.ISO8859-1 pl_PL.ISO8859-2 \
|
||||
uk_UA.KOI8-U pt_BR.ISO8859-1 ru_RU.KOI8-R hu_HU.ISO8859-2
|
||||
|
||||
NLSLINKS_en_US.US-ASCII= en_US.ISO8859-1 en_US.ISO8859-15
|
||||
NLSLINKS_C= en_US.ISO8859-1 en_US.ISO8859-15
|
||||
NLSLINKS_fr_FR.ISO8859-1= fr_BE.ISO8859-1 fr_BE.ISO8859-15 \
|
||||
fr_CA.ISO8859-1 fr_CA.ISO8859-15 fr_CH.ISO8859-1 fr_CH.ISO8859-15 \
|
||||
fr_FR.ISO8859-15
|
||||
|
Loading…
Reference in New Issue
Block a user