sync with OpenBSD -current

This commit is contained in:
purplerain 2023-11-20 02:38:22 +00:00
parent a7acbdeab0
commit c22b8a6120
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
202 changed files with 3004 additions and 4921 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio.c,v 1.18 2023/11/09 14:07:18 dlg Exp $ */
/* $OpenBSD: bio.c,v 1.19 2023/11/15 23:57:45 dlg Exp $ */
/*
* Copyright (c) 2002 Niklas Hallqvist. All rights reserved.
@ -31,18 +31,33 @@
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/tree.h>
#include <sys/systm.h>
#include <dev/biovar.h>
struct bio_mapping {
LIST_ENTRY(bio_mapping) bm_link;
RBT_ENTRY(bio_mapping) bm_link;
uintptr_t bm_cookie;
struct device *bm_dev;
int (*bm_ioctl)(struct device *, u_long, caddr_t);
};
LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios);
RBT_HEAD(bio_mappings, bio_mapping);
static inline int
bio_cookie_cmp(const struct bio_mapping *a, const struct bio_mapping *b)
{
if (a->bm_cookie < b->bm_cookie)
return (1);
if (a->bm_cookie > b->bm_cookie)
return (-1);
return (0);
}
RBT_PROTOTYPE(bio_mappings, bio_mapping, bm_link, bio_cookie_cmp);
struct bio_mappings bios = RBT_INITIALIZER();
void bioattach(int);
int bioclose(dev_t, int, int, struct proc *);
@ -51,7 +66,7 @@ int bioopen(dev_t, int, int, struct proc *);
int bio_delegate_ioctl(struct bio_mapping *, u_long, caddr_t);
struct bio_mapping *bio_lookup(char *);
int bio_validate(void *);
struct bio_mapping *bio_validate(void *);
void
bioattach(int nunits)
@ -73,6 +88,7 @@ bioclose(dev_t dev, int flags, int mode, struct proc *p)
int
bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct bio_mapping *bm;
struct bio_locate *locate;
struct bio *bio;
char name[16];
@ -84,18 +100,19 @@ bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = copyinstr(locate->bl_name, name, sizeof name, NULL);
if (error != 0)
return (error);
locate->bl_bio.bio_cookie = bio_lookup(name);
if (locate->bl_bio.bio_cookie == NULL)
bm = bio_lookup(name);
if (bm == NULL)
return (ENOENT);
locate->bl_bio.bio_cookie = (void *)bm->bm_cookie;
break;
default:
bio = (struct bio *)addr;
if (!bio_validate(bio->bio_cookie))
bm = bio_validate(bio->bio_cookie);
if (bm == NULL)
return (ENOENT);
error = bio_delegate_ioctl(
(struct bio_mapping *)bio->bio_cookie, cmd, addr);
error = bio_delegate_ioctl(bm, cmd, addr);
break;
}
@ -112,7 +129,10 @@ bio_register(struct device *dev, int (*ioctl)(struct device *, u_long, caddr_t))
return (ENOMEM);
bm->bm_dev = dev;
bm->bm_ioctl = ioctl;
LIST_INSERT_HEAD(&bios, bm, bm_link);
do {
bm->bm_cookie = arc4random();
/* lets hope we don't have 4 billion bio_registers */
} while (RBT_INSERT(bio_mappings, &bios, bm) != NULL);
return (0);
}
@ -121,11 +141,9 @@ bio_unregister(struct device *dev)
{
struct bio_mapping *bm, *next;
for (bm = LIST_FIRST(&bios); bm != NULL; bm = next) {
next = LIST_NEXT(bm, bm_link);
RBT_FOREACH_SAFE(bm, bio_mappings, &bios, next) {
if (dev == bm->bm_dev) {
LIST_REMOVE(bm, bm_link);
RBT_REMOVE(bio_mappings, &bios, bm);
free(bm, M_DEVBUF, sizeof(*bm));
}
}
@ -136,21 +154,20 @@ bio_lookup(char *name)
{
struct bio_mapping *bm;
LIST_FOREACH(bm, &bios, bm_link)
RBT_FOREACH(bm, bio_mappings, &bios) {
if (strcmp(name, bm->bm_dev->dv_xname) == 0)
return (bm);
}
return (NULL);
}
int
struct bio_mapping *
bio_validate(void *cookie)
{
struct bio_mapping *bm;
struct bio_mapping key = { .bm_cookie = (uintptr_t)cookie };
LIST_FOREACH(bm, &bios, bm_link)
if (bm == cookie)
return (1);
return (0);
return (RBT_FIND(bio_mappings, &bios, &key));
}
int
@ -218,3 +235,5 @@ bio_status(struct bio_status *bs, int print, int msg_type, const char *fmt,
if (print)
printf("%s: %s\n", bs->bs_controller, bs->bs_msgs[idx].bm_msg);
}
RBT_GENERATE(bio_mappings, bio_mapping, bm_link, bio_cookie_cmp);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: subr_disk.c,v 1.271 2023/02/10 07:00:12 miod Exp $ */
/* $OpenBSD: subr_disk.c,v 1.272 2023/11/15 20:23:19 kn Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@ -1754,7 +1754,7 @@ done:
}
int
disk_map(char *path, char *mappath, int size, int flags)
disk_map(const char *path, char *mappath, int size, int flags)
{
struct disk *dk, *mdk;
u_char uid[8];

View file

@ -489,7 +489,11 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
* symbols from which it is being constructed.
*/
#ifdef LIT_MEM
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 5);
#else
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
#endif
s->pending_buf_size = (ulg)s->lit_bufsize * 4;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
@ -499,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
deflateEnd (strm);
return Z_MEM_ERROR;
}
#ifdef LIT_MEM
s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
s->sym_end = s->lit_bufsize - 1;
#else
s->sym_buf = s->pending_buf + s->lit_bufsize;
s->sym_end = (s->lit_bufsize - 1) * 3;
#endif
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
@ -716,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
#ifdef LIT_MEM
if (bits < 0 || bits > 16 ||
(uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#else
if (bits < 0 || bits > 16 ||
s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#endif
do {
put = Buf_size - s->bi_valid;
if (put > bits)
@ -1304,7 +1320,12 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
#ifdef LIT_MEM
ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
#else
ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
#endif
ds->l_desc.dyn_tree = ds->dyn_ltree;
ds->d_desc.dyn_tree = ds->dyn_dtree;

View file

@ -21,6 +21,10 @@
# define GZIP
#endif
/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at
the cost of a larger memory footprint */
/* #define LIT_MEM */
/* ===========================================================================
* Internal compression state.
*/
@ -215,7 +219,12 @@ typedef struct internal_state {
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
#ifdef LIT_MEM
ushf *d_buf; /* buffer for distances */
uchf *l_buf; /* buffer for literals/lengths */
#else
uchf *sym_buf; /* buffer for distances and literals/lengths */
#endif
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
@ -237,7 +246,7 @@ typedef struct internal_state {
* - I can't count above 4
*/
uInt sym_next; /* running index in sym_buf */
uInt sym_next; /* running index in symbol buffer */
uInt sym_end; /* symbol table full when sym_next reaches this */
ulg opt_len; /* bit length of current block with optimal trees */
@ -316,6 +325,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
extern const uch ZLIB_INTERNAL _dist_code[];
#endif
#ifdef LIT_MEM
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->sym_next] = 0; \
s->l_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \
ush dist = (ush)(distance); \
s->d_buf[s->sym_next] = dist; \
s->l_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#else
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->sym_buf[s->sym_next++] = 0; \
@ -335,6 +363,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#endif
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \

View file

@ -1473,7 +1473,7 @@ int ZEXPORT inflateSync(z_streamp strm) {
/* if first time, start search in bit buffer */
if (state->mode != SYNC) {
state->mode = SYNC;
state->hold <<= state->bits & 7;
state->hold >>= state->bits & 7;
state->bits -= state->bits & 7;
len = 0;
while (state->bits >= 8) {

View file

@ -55,7 +55,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203};
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 70, 200};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,

View file

@ -41,8 +41,8 @@ typedef struct {
examples/enough.c found in the zlib distribution. The arguments to that
program are the number of symbols, the initial root table size, and the
maximum bit length of a code. "enough 286 9 15" for literal/length codes
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
The initial root table size (9 or 6) is found in the fifth argument of the
returns 852, and "enough 30 6 15" for distance codes returns 592. The
initial root table size (9 or 6) is found in the fifth argument of the
inflate_table() calls in inflate.c and infback.c. If the root table size is
changed, then these maximum sizes would be need to be recalculated and
updated. */

View file

@ -897,14 +897,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree,
const ct_data *dtree) {
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
unsigned sx = 0; /* running index in sym_buf */
unsigned sx = 0; /* running index in symbol buffers */
unsigned code; /* the code to send */
int extra; /* number of extra bits to send */
if (s->sym_next != 0) do {
#ifdef LIT_MEM
dist = s->d_buf[sx];
lc = s->l_buf[sx++];
#else
dist = s->sym_buf[sx++] & 0xff;
dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
lc = s->sym_buf[sx++];
#endif
if (dist == 0) {
send_code(s, lc, ltree); /* send a literal byte */
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
@ -929,8 +934,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree,
}
} /* literal or match pair ? */
/* Check that the overlay between pending_buf and sym_buf is ok: */
/* Check for no overlay of pending_buf on needed symbols */
#ifdef LIT_MEM
Assert(s->pending < (s->lit_bufsize << 1) + sx, "pendingBuf overflow");
#else
Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
#endif
} while (sx < s->sym_next);
@ -1080,9 +1089,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
* the current block must be flushed.
*/
int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
#ifdef LIT_MEM
s->d_buf[s->sym_next] = (ush)dist;
s->l_buf[s->sym_next++] = (uch)lc;
#else
s->sym_buf[s->sym_next++] = (uch)dist;
s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
s->sym_buf[s->sym_next++] = (uch)lc;
#endif
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;

View file

@ -1,5 +1,5 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.3, August 18th, 2023
version 1.3.0.1, August xxth, 2023
Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler
@ -37,12 +37,12 @@
extern "C" {
#endif
#define ZLIB_VERSION "1.3"
#define ZLIB_VERNUM 0x1300
#define ZLIB_VERSION "1.3.0.1-motley"
#define ZLIB_VERNUM 0x1301
#define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 3
#define ZLIB_VER_REVISION 0
#define ZLIB_VER_SUBREVISION 0
#define ZLIB_VER_SUBREVISION 1
/*
The 'zlib' compression library provides in-memory compression and
@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm);
inflateSync returns Z_OK if a possible full flush point has been found,
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
In the success case, the application may save the current current value of
total_in which indicates where valid compressed data was found. In the
error case, the application may repeatedly call inflateSync, providing more
input each time, until success or end of the input data.
In the success case, the application may save the current value of total_in
which indicates where valid compressed data was found. In the error case,
the application may repeatedly call inflateSync, providing more input each
time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy(z_streamp dest,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_vxlan.c,v 1.94 2023/10/27 20:56:48 jan Exp $ */
/* $OpenBSD: if_vxlan.c,v 1.95 2023/11/18 00:23:38 dlg Exp $ */
/*
* Copyright (c) 2021 David Gwynne <dlg@openbsd.org>
@ -1346,6 +1346,9 @@ vxlan_set_tunnel(struct vxlan_softc *sc, const struct if_laddrreq *req)
if (in_nullhost(dst4->sin_addr))
return (EINVAL);
if (dst4->sin_port != htons(0))
return (EINVAL);
/* all good */
mode = IN_MULTICAST(dst4->sin_addr.s_addr) ?
VXLAN_TMODE_LEARNING : VXLAN_TMODE_P2P;
@ -1376,6 +1379,9 @@ vxlan_set_tunnel(struct vxlan_softc *sc, const struct if_laddrreq *req)
if (src6->sin6_scope_id != dst6->sin6_scope_id)
return (EINVAL);
if (dst6->sin6_port != htons(0))
return (EINVAL);
/* all good */
mode = IN6_IS_ADDR_MULTICAST(&dst6->sin6_addr) ?
VXLAN_TMODE_LEARNING : VXLAN_TMODE_P2P;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_input.c,v 1.391 2023/09/03 21:37:17 bluhm Exp $ */
/* $OpenBSD: tcp_input.c,v 1.392 2023/11/16 18:27:48 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@ -3084,15 +3084,24 @@ tcp_mss_adv(struct mbuf *m, int af)
* state for SYN_RECEIVED.
*/
/*
* Locks used to protect global data and struct members:
* N net lock
* S syn_cache_mtx tcp syn cache global mutex
*/
/* syn hash parameters */
int tcp_syn_hash_size = TCP_SYN_HASH_SIZE;
int tcp_syn_cache_limit = TCP_SYN_HASH_SIZE*TCP_SYN_BUCKET_SIZE;
int tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
int tcp_syn_use_limit = 100000;
int tcp_syn_hash_size = TCP_SYN_HASH_SIZE; /* [N] size of hash table */
int tcp_syn_cache_limit = /* [N] global entry limit */
TCP_SYN_HASH_SIZE * TCP_SYN_BUCKET_SIZE;
int tcp_syn_bucket_limit = /* [N] per bucket limit */
3 * TCP_SYN_BUCKET_SIZE;
int tcp_syn_use_limit = 100000; /* [N] reseed after uses */
struct pool syn_cache_pool;
struct syn_cache_set tcp_syn_cache[2];
int tcp_syn_cache_active;
struct mutex syn_cache_mtx = MUTEX_INITIALIZER(IPL_SOFTNET);
#define SYN_HASH(sa, sp, dp, rand) \
(((sa)->s_addr ^ (rand)[0]) * \
@ -3134,7 +3143,10 @@ do { \
void
syn_cache_rm(struct syn_cache *sc)
{
sc->sc_flags |= SCF_DEAD;
MUTEX_ASSERT_LOCKED(&syn_cache_mtx);
KASSERT(!ISSET(sc->sc_dynflags, SCF_DEAD));
SET(sc->sc_dynflags, SCF_DEAD);
TAILQ_REMOVE(&sc->sc_buckethead->sch_bucket, sc, sc_bucketq);
sc->sc_tp = NULL;
LIST_REMOVE(sc, sc_tpq);
@ -3151,11 +3163,10 @@ syn_cache_put(struct syn_cache *sc)
if (refcnt_rele(&sc->sc_refcnt) == 0)
return;
/* Dealing with last reference, no lock needed. */
m_free(sc->sc_ipopts);
if (sc->sc_route4.ro_rt != NULL) {
rtfree(sc->sc_route4.ro_rt);
sc->sc_route4.ro_rt = NULL;
}
rtfree(sc->sc_route4.ro_rt);
pool_put(&syn_cache_pool, sc);
}
@ -3190,6 +3201,7 @@ syn_cache_insert(struct syn_cache *sc, struct tcpcb *tp)
int i;
NET_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&syn_cache_mtx);
/*
* If there are no entries in the hash table, reinitialize
@ -3333,12 +3345,10 @@ syn_cache_timer(void *arg)
uint64_t now;
int lastref;
NET_LOCK();
if (sc->sc_flags & SCF_DEAD)
mtx_enter(&syn_cache_mtx);
if (ISSET(sc->sc_dynflags, SCF_DEAD))
goto freeit;
now = tcp_now();
if (__predict_false(sc->sc_rxtshift == TCP_MAXRXTSHIFT)) {
/* Drop it -- too many retransmissions. */
goto dropit;
@ -3353,18 +3363,22 @@ syn_cache_timer(void *arg)
if (sc->sc_rxttot >= tcptv_keep_init)
goto dropit;
tcpstat_inc(tcps_sc_retransmitted);
(void) syn_cache_respond(sc, NULL, now);
/* Advance the timer back-off. */
sc->sc_rxtshift++;
TCPT_RANGESET(sc->sc_rxtcur,
TCPTV_SRTTDFLT * tcp_backoff[sc->sc_rxtshift], TCPTV_MIN,
TCPTV_REXMTMAX);
if (!timeout_add_msec(&sc->sc_timer, sc->sc_rxtcur))
syn_cache_put(sc);
if (timeout_add_msec(&sc->sc_timer, sc->sc_rxtcur))
refcnt_take(&sc->sc_refcnt);
mtx_leave(&syn_cache_mtx);
NET_LOCK();
now = tcp_now();
(void) syn_cache_respond(sc, NULL, now);
tcpstat_inc(tcps_sc_retransmitted);
NET_UNLOCK();
syn_cache_put(sc);
return;
dropit:
@ -3375,8 +3389,8 @@ syn_cache_timer(void *arg)
KASSERT(lastref == 0);
(void)lastref;
freeit:
mtx_leave(&syn_cache_mtx);
syn_cache_put(sc);
NET_UNLOCK();
}
/*
@ -3391,6 +3405,7 @@ syn_cache_cleanup(struct tcpcb *tp)
NET_ASSERT_LOCKED();
mtx_enter(&syn_cache_mtx);
LIST_FOREACH_SAFE(sc, &tp->t_sc, sc_tpq, nsc) {
#ifdef DIAGNOSTIC
if (sc->sc_tp != tp)
@ -3399,8 +3414,9 @@ syn_cache_cleanup(struct tcpcb *tp)
syn_cache_rm(sc);
syn_cache_put(sc);
}
/* just for safety */
LIST_INIT(&tp->t_sc);
mtx_leave(&syn_cache_mtx);
KASSERT(LIST_EMPTY(&tp->t_sc));
}
/*
@ -3417,6 +3433,7 @@ syn_cache_lookup(struct sockaddr *src, struct sockaddr *dst,
int i;
NET_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&syn_cache_mtx);
/* Check the active cache first, the passive cache is likely empty. */
sets[0] = &tcp_syn_cache[tcp_syn_cache_active];
@ -3475,9 +3492,12 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
NET_ASSERT_LOCKED();
mtx_enter(&syn_cache_mtx);
sc = syn_cache_lookup(src, dst, &scp, sotoinpcb(so)->inp_rtableid);
if (sc == NULL)
if (sc == NULL) {
mtx_leave(&syn_cache_mtx);
return (NULL);
}
/*
* Verify the sequence and ack numbers. Try getting the correct
@ -3486,12 +3506,16 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
if ((th->th_ack != sc->sc_iss + 1) ||
SEQ_LEQ(th->th_seq, sc->sc_irs) ||
SEQ_GT(th->th_seq, sc->sc_irs + 1 + sc->sc_win)) {
refcnt_take(&sc->sc_refcnt);
mtx_leave(&syn_cache_mtx);
(void) syn_cache_respond(sc, m, now);
syn_cache_put(sc);
return ((struct socket *)(-1));
}
/* Remove this cache entry */
syn_cache_rm(sc);
mtx_leave(&syn_cache_mtx);
/*
* Ok, create the full blown connection, and set things up
@ -3590,7 +3614,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
tp->request_r_scale = sc->sc_request_r_scale;
tp->t_flags |= TF_REQ_SCALE|TF_RCVD_SCALE;
}
if (sc->sc_flags & SCF_TIMESTAMP)
if (ISSET(sc->sc_fixflags, SCF_TIMESTAMP))
tp->t_flags |= TF_REQ_TSTMP|TF_RCVD_TSTMP;
tp->t_template = tcp_template(tp);
@ -3599,7 +3623,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
so = NULL;
goto abort;
}
tp->sack_enable = sc->sc_flags & SCF_SACK_PERMIT;
tp->sack_enable = ISSET(sc->sc_fixflags, SCF_SACK_PERMIT);
tp->ts_modulate = sc->sc_modulate;
tp->ts_recent = sc->sc_timestamp;
tp->iss = sc->sc_iss;
@ -3607,15 +3631,15 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
tcp_sendseqinit(tp);
tp->snd_last = tp->snd_una;
#ifdef TCP_ECN
if (sc->sc_flags & SCF_ECN_PERMIT) {
if (ISSET(sc->sc_fixflags, SCF_ECN_PERMIT)) {
tp->t_flags |= TF_ECN_PERMIT;
tcpstat_inc(tcps_ecn_accepts);
}
#endif
if (sc->sc_flags & SCF_SACK_PERMIT)
if (ISSET(sc->sc_fixflags, SCF_SACK_PERMIT))
tp->t_flags |= TF_SACK_PERMIT;
#ifdef TCP_SIGNATURE
if (sc->sc_flags & SCF_SIGNATURE)
if (ISSET(sc->sc_fixflags, SCF_SIGNATURE))
tp->t_flags |= TF_SIGNATURE;
#endif
tcp_rcvseqinit(tp);
@ -3631,7 +3655,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
if (sc->sc_peermaxseg)
tcp_mss_update(tp);
/* Reset initial window to 1 segment for retransmit */
if (sc->sc_rxtshift > 0)
if (READ_ONCE(sc->sc_rxtshift) > 0)
tp->snd_cwnd = tp->t_maxseg;
tp->snd_wl1 = sc->sc_irs;
tp->rcv_up = sc->sc_irs + 1;
@ -3678,12 +3702,19 @@ syn_cache_reset(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
NET_ASSERT_LOCKED();
if ((sc = syn_cache_lookup(src, dst, &scp, rtableid)) == NULL)
mtx_enter(&syn_cache_mtx);
sc = syn_cache_lookup(src, dst, &scp, rtableid);
if (sc == NULL) {
mtx_leave(&syn_cache_mtx);
return;
}
if (SEQ_LT(th->th_seq, sc->sc_irs) ||
SEQ_GT(th->th_seq, sc->sc_irs + 1))
SEQ_GT(th->th_seq, sc->sc_irs + 1)) {
mtx_leave(&syn_cache_mtx);
return;
}
syn_cache_rm(sc);
mtx_leave(&syn_cache_mtx);
tcpstat_inc(tcps_sc_reset);
syn_cache_put(sc);
}
@ -3697,10 +3728,15 @@ syn_cache_unreach(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
NET_ASSERT_LOCKED();
if ((sc = syn_cache_lookup(src, dst, &scp, rtableid)) == NULL)
mtx_enter(&syn_cache_mtx);
sc = syn_cache_lookup(src, dst, &scp, rtableid);
if (sc == NULL) {
mtx_leave(&syn_cache_mtx);
return;
}
/* If the sequence number != sc_iss, then it's a bogus ICMP msg */
if (ntohl (th->th_seq) != sc->sc_iss) {
mtx_leave(&syn_cache_mtx);
return;
}
@ -3712,12 +3748,14 @@ syn_cache_unreach(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
*
* See tcp_notify().
*/
if ((sc->sc_flags & SCF_UNREACH) == 0 || sc->sc_rxtshift < 3) {
sc->sc_flags |= SCF_UNREACH;
if (!ISSET(sc->sc_dynflags, SCF_UNREACH) || sc->sc_rxtshift < 3) {
SET(sc->sc_dynflags, SCF_UNREACH);
mtx_leave(&syn_cache_mtx);
return;
}
syn_cache_rm(sc);
mtx_leave(&syn_cache_mtx);
tcpstat_inc(tcps_sc_unreach);
syn_cache_put(sc);
}
@ -3747,6 +3785,8 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
struct syn_cache_head *scp;
struct mbuf *ipopts;
NET_ASSERT_LOCKED();
tp = sototcpcb(so);
/*
@ -3797,8 +3837,11 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
* If we do, resend the SYN,ACK. We do not count this
* as a retransmission (XXX though maybe we should).
*/
mtx_enter(&syn_cache_mtx);
sc = syn_cache_lookup(src, dst, &scp, sotoinpcb(so)->inp_rtableid);
if (sc != NULL) {
refcnt_take(&sc->sc_refcnt);
mtx_leave(&syn_cache_mtx);
tcpstat_inc(tcps_sc_dupesyn);
if (ipopts) {
/*
@ -3813,8 +3856,10 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
tcpstat_inc(tcps_sndacks);
tcpstat_inc(tcps_sndtotal);
}
syn_cache_put(sc);
return (0);
}
mtx_leave(&syn_cache_mtx);
sc = pool_get(&syn_cache_pool, PR_NOWAIT|PR_ZERO);
if (sc == NULL) {
@ -3831,7 +3876,6 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
memcpy(&sc->sc_src, src, src->sa_len);
memcpy(&sc->sc_dst, dst, dst->sa_len);
sc->sc_rtableid = sotoinpcb(so)->inp_rtableid;
sc->sc_flags = 0;
sc->sc_ipopts = ipopts;
sc->sc_irs = th->th_seq;
@ -3842,7 +3886,7 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
sc->sc_timestamp = tb.ts_recent;
if ((tb.t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP)) ==
(TF_REQ_TSTMP|TF_RCVD_TSTMP)) {
sc->sc_flags |= SCF_TIMESTAMP;
SET(sc->sc_fixflags, SCF_TIMESTAMP);
sc->sc_modulate = arc4random();
}
if ((tb.t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
@ -3882,21 +3926,28 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
*/
if (tcp_do_ecn &&
(th->th_flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR))
sc->sc_flags |= SCF_ECN_PERMIT;
SET(sc->sc_fixflags, SCF_ECN_PERMIT);
#endif
/*
* Set SCF_SACK_PERMIT if peer did send a SACK_PERMITTED option
* (i.e., if tcp_dooptions() did set TF_SACK_PERMIT).
*/
if (tb.sack_enable && (tb.t_flags & TF_SACK_PERMIT))
sc->sc_flags |= SCF_SACK_PERMIT;
SET(sc->sc_fixflags, SCF_SACK_PERMIT);
#ifdef TCP_SIGNATURE
if (tb.t_flags & TF_SIGNATURE)
sc->sc_flags |= SCF_SIGNATURE;
SET(sc->sc_fixflags, SCF_SIGNATURE);
#endif
sc->sc_tp = tp;
if (syn_cache_respond(sc, m, now) == 0) {
mtx_enter(&syn_cache_mtx);
/*
* XXXSMP Currently exclusive netlock prevents another insert
* after our syn_cache_lookup() and before syn_cache_insert().
* Double insert should be handled and not rely on netlock.
*/
syn_cache_insert(sc, tp);
mtx_leave(&syn_cache_mtx);
tcpstat_inc(tcps_sndacks);
tcpstat_inc(tcps_sndtotal);
} else {
@ -3921,6 +3972,8 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
u_int hlen;
struct inpcb *inp;
NET_ASSERT_LOCKED();
switch (sc->sc_src.sa.sa_family) {
case AF_INET:
hlen = sizeof(struct ip);
@ -3937,11 +3990,11 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
/* Compute the size of the TCP options. */
optlen = 4 + (sc->sc_request_r_scale != 15 ? 4 : 0) +
((sc->sc_flags & SCF_SACK_PERMIT) ? 4 : 0) +
(ISSET(sc->sc_fixflags, SCF_SACK_PERMIT) ? 4 : 0) +
#ifdef TCP_SIGNATURE
((sc->sc_flags & SCF_SIGNATURE) ? TCPOLEN_SIGLEN : 0) +
(ISSET(sc->sc_fixflags, SCF_SIGNATURE) ? TCPOLEN_SIGLEN : 0) +
#endif
((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);
(ISSET(sc->sc_fixflags, SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);
tlen = hlen + sizeof(struct tcphdr) + optlen;
@ -4000,7 +4053,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
th->th_flags = TH_SYN|TH_ACK;
#ifdef TCP_ECN
/* Set ECE for SYN-ACK if peer supports ECN. */
if (tcp_do_ecn && (sc->sc_flags & SCF_ECN_PERMIT))
if (tcp_do_ecn && ISSET(sc->sc_fixflags, SCF_ECN_PERMIT))
th->th_flags |= TH_ECE;
#endif
th->th_win = htons(sc->sc_win);
@ -4015,7 +4068,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
*optp++ = sc->sc_ourmaxseg & 0xff;
/* Include SACK_PERMIT_HDR option if peer has already done so. */
if (sc->sc_flags & SCF_SACK_PERMIT) {
if (ISSET(sc->sc_fixflags, SCF_SACK_PERMIT)) {
*((u_int32_t *)optp) = htonl(TCPOPT_SACK_PERMIT_HDR);
optp += 4;
}
@ -4027,7 +4080,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
optp += 4;
}
if (sc->sc_flags & SCF_TIMESTAMP) {
if (ISSET(sc->sc_fixflags, SCF_TIMESTAMP)) {
u_int32_t *lp = (u_int32_t *)(optp);
/* Form timestamp option as shown in appendix A of RFC 1323. */
*lp++ = htonl(TCPOPT_TSTAMP_HDR);
@ -4037,7 +4090,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
}
#ifdef TCP_SIGNATURE
if (sc->sc_flags & SCF_SIGNATURE) {
if (ISSET(sc->sc_fixflags, SCF_SIGNATURE)) {
union sockaddr_union src, dst;
struct tdb *tdb;
@ -4093,7 +4146,9 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT);
/* use IPsec policy and ttl from listening socket, on SYN ACK */
mtx_enter(&syn_cache_mtx);
inp = sc->sc_tp ? sc->sc_tp->t_inpcb : NULL;
mtx_leave(&syn_cache_mtx);
/*
* Fill in some straggling IP bits. Note the stack expects

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_usrreq.c,v 1.222 2023/09/16 09:33:27 mpi Exp $ */
/* $OpenBSD: tcp_usrreq.c,v 1.223 2023/11/16 18:27:48 bluhm Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@ -1347,6 +1347,7 @@ tcp_sysctl_tcpstat(void *oldp, size_t *oldlenp, void *newp)
#undef ASSIGN
mtx_enter(&syn_cache_mtx);
set = &tcp_syn_cache[tcp_syn_cache_active];
tcpstat.tcps_sc_hash_size = set->scs_size;
tcpstat.tcps_sc_entry_count = set->scs_count;
@ -1360,6 +1361,7 @@ tcp_sysctl_tcpstat(void *oldp, size_t *oldlenp, void *newp)
}
tcpstat.tcps_sc_bucket_limit = tcp_syn_bucket_limit;
tcpstat.tcps_sc_uses_left = set->scs_use;
mtx_leave(&syn_cache_mtx);
return (sysctl_rdstruct(oldp, oldlenp, newp,
&tcpstat, sizeof(tcpstat)));
@ -1473,10 +1475,12 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
* Global tcp_syn_use_limit is used when reseeding a
* new cache. Also update the value in active cache.
*/
mtx_enter(&syn_cache_mtx);
if (tcp_syn_cache[0].scs_use > tcp_syn_use_limit)
tcp_syn_cache[0].scs_use = tcp_syn_use_limit;
if (tcp_syn_cache[1].scs_use > tcp_syn_use_limit)
tcp_syn_cache[1].scs_use = tcp_syn_use_limit;
mtx_leave(&syn_cache_mtx);
}
NET_UNLOCK();
return (error);
@ -1492,11 +1496,13 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
* switch sets as soon as possible. Then
* the actual hash array will be reallocated.
*/
mtx_enter(&syn_cache_mtx);
if (tcp_syn_cache[0].scs_size != nval)
tcp_syn_cache[0].scs_use = 0;
if (tcp_syn_cache[1].scs_size != nval)
tcp_syn_cache[1].scs_use = 0;
tcp_syn_hash_size = nval;
mtx_leave(&syn_cache_mtx);
}
NET_UNLOCK();
return (error);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_var.h,v 1.171 2023/09/04 23:00:36 bluhm Exp $ */
/* $OpenBSD: tcp_var.h,v 1.172 2023/11/16 18:27:48 bluhm Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@ -225,6 +225,15 @@ struct tcp_opt_info {
* Data for the TCP compressed state engine.
*/
/*
* Locks used to protect global data and struct members:
* I immutable after creation
* N net lock
* S syn_cache_mtx tcp syn cache global mutex
*/
extern struct mutex syn_cache_mtx;
#define TCP_SYN_HASH_SIZE 293
#define TCP_SYN_BUCKET_SIZE 35
@ -235,7 +244,7 @@ union syn_cache_sa {
};
struct syn_cache {
TAILQ_ENTRY(syn_cache) sc_bucketq; /* link on bucket list */
TAILQ_ENTRY(syn_cache) sc_bucketq; /* [S] link on bucket list */
struct refcnt sc_refcnt; /* ref count list and timer */
struct timeout sc_timer; /* rexmt timer */
union { /* cached route */
@ -244,54 +253,55 @@ struct syn_cache {
struct route_in6 route6;
#endif
} sc_route_u;
#define sc_route4 sc_route_u.route4
#define sc_route4 sc_route_u.route4 /* [N] */
#ifdef INET6
#define sc_route6 sc_route_u.route6
#define sc_route6 sc_route_u.route6 /* [N] */
#endif
long sc_win; /* advertised window */
struct syn_cache_head *sc_buckethead; /* our bucket index */
struct syn_cache_set *sc_set; /* our syn cache set */
u_int64_t sc_timestamp; /* timestamp from SYN */
u_int32_t sc_hash;
u_int32_t sc_modulate; /* our timestamp modulator */
union syn_cache_sa sc_src;
union syn_cache_sa sc_dst;
tcp_seq sc_irs;
tcp_seq sc_iss;
u_int sc_rtableid;
u_int sc_rxtcur; /* current rxt timeout */
u_int sc_rxttot; /* total time spend on queues */
u_short sc_rxtshift; /* for computing backoff */
u_short sc_flags;
long sc_win; /* [I] advertised window */
struct syn_cache_head *sc_buckethead; /* [S] our bucket index */
struct syn_cache_set *sc_set; /* [S] our syn cache set */
u_int64_t sc_timestamp; /* [N] timestamp from SYN */
u_int32_t sc_hash; /* [S] */
u_int32_t sc_modulate; /* [I] our timestamp modulator */
union syn_cache_sa sc_src; /* [I] */
union syn_cache_sa sc_dst; /* [I] */
tcp_seq sc_irs; /* [I] */
tcp_seq sc_iss; /* [I] */
u_int sc_rtableid; /* [I] */
u_int sc_rxtcur; /* [S] current rxt timeout */
u_int sc_rxttot; /* [S] total time spend on queues */
u_int sc_rxtshift; /* [S] for computing backoff */
u_int sc_dynflags; /* [S] flags accessed with mutex */
#define SCF_UNREACH 0x0001U /* we've had an unreach error */
#define SCF_DEAD 0x0002U /* this entry to be released */
#define SCF_UNREACH 0x0001 /* we've had an unreach error */
#define SCF_TIMESTAMP 0x0002 /* peer will do timestamps */
#define SCF_DEAD 0x0004 /* this entry to be released */
#define SCF_SACK_PERMIT 0x0008 /* permit sack */
#define SCF_ECN_PERMIT 0x0010 /* permit ecn */
#define SCF_SIGNATURE 0x0020 /* enforce tcp signatures */
u_short sc_fixflags; /* [I] set during initialization */
#define SCF_TIMESTAMP 0x0010U /* peer will do timestamps */
#define SCF_SACK_PERMIT 0x0020U /* permit sack */
#define SCF_ECN_PERMIT 0x0040U /* permit ecn */
#define SCF_SIGNATURE 0x0080U /* enforce tcp signatures */
struct mbuf *sc_ipopts; /* IP options */
u_int16_t sc_peermaxseg;
u_int16_t sc_ourmaxseg;
u_int sc_request_r_scale : 4,
sc_requested_s_scale : 4;
struct mbuf *sc_ipopts; /* [N] IP options */
u_int16_t sc_peermaxseg; /* [I] */
u_int16_t sc_ourmaxseg; /* [I] */
u_int sc_request_r_scale : 4, /* [I] */
sc_requested_s_scale : 4; /* [I] */
struct tcpcb *sc_tp; /* tcb for listening socket */
LIST_ENTRY(syn_cache) sc_tpq; /* list of entries by same tp */
struct tcpcb *sc_tp; /* [S] tcb for listening socket */
LIST_ENTRY(syn_cache) sc_tpq; /* [S] list of entries by same tp */
};
struct syn_cache_head {
TAILQ_HEAD(, syn_cache) sch_bucket; /* bucket entries */
u_short sch_length; /* # entries in bucket */
TAILQ_HEAD(, syn_cache) sch_bucket; /* [S] bucket entries */
u_short sch_length; /* [S] # entries in bucket */
};
struct syn_cache_set {
struct syn_cache_head *scs_buckethead;
long scs_use;
int scs_size;
int scs_count;
u_int32_t scs_random[5];
struct syn_cache_head *scs_buckethead; /* [S] */
long scs_use; /* [S] */
int scs_size; /* [S] current size of hash table */
int scs_count; /* [S] */
u_int32_t scs_random[5]; /* [S] */
};
#endif /* _KERNEL */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: disk.h,v 1.37 2022/09/11 19:34:40 miod Exp $ */
/* $OpenBSD: disk.h,v 1.38 2023/11/15 20:23:19 kn Exp $ */
/* $NetBSD: disk.h,v 1.11 1996/04/28 20:22:50 thorpej Exp $ */
/*
@ -152,7 +152,7 @@ struct device *disk_lookup(struct cfdriver *, int);
char *disk_readlabel(struct disklabel *, dev_t, char *, size_t);
int disk_map(char *, char *, int, int);
int disk_map(const char *, char *, int, int);
int duid_iszero(u_char *);
const char *duid_format(u_char *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kstat.h,v 1.3 2022/04/22 00:27:55 dlg Exp $ */
/* $OpenBSD: kstat.h,v 1.4 2023/11/16 02:45:20 dlg Exp $ */
/*
* Copyright (c) 2020 David Gwynne <dlg@openbsd.org>
@ -82,6 +82,9 @@ enum kstat_kv_type {
KSTAT_KV_T_COUNTER16,
KSTAT_KV_T_UINT16,
KSTAT_KV_T_INT16,
KSTAT_KV_T_FREQ, /* frequency (Hz) */
KSTAT_KV_T_VOLTS_DC, /* voltage (uV DC) */
KSTAT_KV_T_VOLTS_AC, /* voltage (uV AC) */
};
/* units only apply to integer types */
@ -119,6 +122,8 @@ struct kstat_kv {
#define kstat_kv_s16(_kv) (_kv)->kv_v.v_s16
#define kstat_kv_len(_kv) (_kv)->kv_v.v_len
#define kstat_kv_temp(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_freq(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_volts(_kv) (_kv)->kv_v.v_u64
#ifdef _KERNEL