Adjust PR_WRAP_USRREQS() to include the attach/detach functions.
We still need the kernel-lock for some corner cases.
This commit is contained in:
parent
b0558585a9
commit
e401453f3f
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtsock.c,v 1.145 2014/05/19 02:51:24 rmind Exp $ */
|
||||
/* $NetBSD: rtsock.c,v 1.146 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.145 2014/05/19 02:51:24 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.146 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
@ -1318,14 +1318,14 @@ COMPATNAME(route_init)(void)
|
||||
* Definitions of protocols supported in the ROUTE domain.
|
||||
*/
|
||||
#ifndef COMPAT_RTSOCK
|
||||
PR_WRAP_USRREQ(route_usrreq);
|
||||
PR_WRAP_USRREQS(route);
|
||||
#else
|
||||
PR_WRAP_USRREQ(compat_50_route_usrreq);
|
||||
PR_WRAP_USRREQS(compat_50_route);
|
||||
#endif
|
||||
|
||||
static const struct pr_usrreqs route_usrreqs = {
|
||||
.pr_attach = COMPATNAME(route_attach),
|
||||
.pr_detach = COMPATNAME(route_detach),
|
||||
.pr_attach = COMPATNAME(route_attach_wrapper),
|
||||
.pr_detach = COMPATNAME(route_detach_wrapper),
|
||||
.pr_generic = COMPATNAME(route_usrreq_wrapper),
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ddp_usrreq.c,v 1.43 2014/05/19 02:51:24 rmind Exp $ */
|
||||
/* $NetBSD: ddp_usrreq.c,v 1.44 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1991 Regents of The University of Michigan.
|
||||
@ -27,7 +27,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.43 2014/05/19 02:51:24 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.44 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_mbuftrace.h"
|
||||
|
||||
@ -550,8 +550,9 @@ ddp_init(void)
|
||||
MOWNER_ATTACH(&aarp_mowner);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(ddp_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(ddp)
|
||||
#define ddp_attach ddp_attach_wrapper
|
||||
#define ddp_detach ddp_detach_wrapper
|
||||
#define ddp_usrreq ddp_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs ddp_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hci_socket.c,v 1.23 2014/05/20 18:25:54 rmind Exp $ */
|
||||
/* $NetBSD: hci_socket.c,v 1.24 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.23 2014/05/20 18:25:54 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.24 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
@ -864,10 +864,10 @@ hci_mtap(struct mbuf *m, struct hci_unit *unit)
|
||||
}
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(hci_usrreq)
|
||||
PR_WRAP_USRREQS(hci)
|
||||
|
||||
//#define hci_attach hci_attach_wrapper
|
||||
//#define hci_detach hci_detach_wrapper
|
||||
#define hci_attach hci_attach_wrapper
|
||||
#define hci_detach hci_detach_wrapper
|
||||
#define hci_usrreq hci_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs hci_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: l2cap_socket.c,v 1.14 2014/05/20 18:25:54 rmind Exp $ */
|
||||
/* $NetBSD: l2cap_socket.c,v 1.15 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.14 2014/05/20 18:25:54 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.15 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
@ -411,10 +411,10 @@ l2cap_input(void *arg, struct mbuf *m)
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(l2cap_usrreq)
|
||||
PR_WRAP_USRREQS(l2cap)
|
||||
|
||||
//#define l2cap_attach l2cap_attach_wrapper
|
||||
//#define l2cap_detach l2cap_detach_wrapper
|
||||
#define l2cap_attach l2cap_attach_wrapper
|
||||
#define l2cap_detach l2cap_detach_wrapper
|
||||
#define l2cap_usrreq l2cap_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs l2cap_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rfcomm_socket.c,v 1.15 2014/05/20 18:25:54 rmind Exp $ */
|
||||
/* $NetBSD: rfcomm_socket.c,v 1.16 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.15 2014/05/20 18:25:54 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.16 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
@ -424,10 +424,10 @@ rfcomm_input(void *arg, struct mbuf *m)
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(rfcomm_usrreq)
|
||||
PR_WRAP_USRREQS(rfcomm)
|
||||
|
||||
//#define rfcomm_attach rfcomm_attach_wrapper
|
||||
//#define rfcomm_detach rfcomm_detach_wrapper
|
||||
#define rfcomm_attach rfcomm_attach_wrapper
|
||||
#define rfcomm_detach rfcomm_detach_wrapper
|
||||
#define rfcomm_usrreq rfcomm_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs rfcomm_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sco_socket.c,v 1.16 2014/05/20 18:25:54 rmind Exp $ */
|
||||
/* $NetBSD: sco_socket.c,v 1.17 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.16 2014/05/20 18:25:54 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.17 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
@ -379,10 +379,10 @@ sco_input(void *arg, struct mbuf *m)
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(sco_usrreq)
|
||||
PR_WRAP_USRREQS(sco)
|
||||
|
||||
//#define sco_attach sco_attach_wrapper
|
||||
//#define sco_detach sco_detach_wrapper
|
||||
#define sco_attach sco_attach_wrapper
|
||||
#define sco_detach sco_detach_wrapper
|
||||
#define sco_usrreq sco_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs sco_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: raw_ip.c,v 1.121 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: raw_ip.c,v 1.122 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -65,7 +65,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.121 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.122 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -697,8 +697,9 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
||||
return error;
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(rip_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(rip)
|
||||
#define rip_attach rip_attach_wrapper
|
||||
#define rip_detach rip_detach_wrapper
|
||||
#define rip_usrreq rip_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs rip_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.173 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.174 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -99,7 +99,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.173 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.174 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -2193,8 +2193,9 @@ tcp_usrreq_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(tcp_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(tcp)
|
||||
#define tcp_attach tcp_attach_wrapper
|
||||
#define tcp_detach tcp_detach_wrapper
|
||||
#define tcp_usrreq tcp_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs tcp_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.196 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.197 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.196 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.197 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -1603,8 +1603,9 @@ udp4_espinudp(struct mbuf **mp, int off, struct sockaddr *src,
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_WRAP_USRREQ(udp_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(udp)
|
||||
#define udp_attach udp_attach_wrapper
|
||||
#define udp_detach udp_detach_wrapper
|
||||
#define udp_usrreq udp_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs udp_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: raw_ip6.c,v 1.116 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: raw_ip6.c,v 1.117 2014/05/20 19:04:00 rmind Exp $ */
|
||||
/* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
@ -62,7 +62,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.116 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.117 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
@ -893,8 +893,9 @@ sysctl_net_inet6_raw6_setup(struct sysctllog **clog)
|
||||
CTL_EOL);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(rip6_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(rip6)
|
||||
#define rip6_attach rip6_attach_wrapper
|
||||
#define rip6_detach rip6_detach_wrapper
|
||||
#define rip6_usrreq rip6_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs rip6_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.95 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.96 2014/05/20 19:04:00 rmind Exp $ */
|
||||
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -62,7 +62,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.95 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.96 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
@ -540,8 +540,9 @@ udp6_statinc(u_int stat)
|
||||
UDP6_STATINC(stat);
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(udp6_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(udp6)
|
||||
#define udp6_attach udp6_attach_wrapper
|
||||
#define udp6_detach udp6_detach_wrapper
|
||||
#define udp6_usrreq udp6_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs udp6_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: keysock.c,v 1.23 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: keysock.c,v 1.24 2014/05/20 19:04:00 rmind Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.23 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.24 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
@ -745,8 +745,9 @@ DOMAIN_SET(key);
|
||||
|
||||
DOMAIN_DEFINE(keydomain);
|
||||
|
||||
PR_WRAP_USRREQ(key_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(key)
|
||||
#define key_attach key_attach_wrapper
|
||||
#define key_detach key_detach_wrapper
|
||||
#define key_usrreq key_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs key_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mpls_proto.c,v 1.8 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: mpls_proto.c,v 1.9 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.8 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.9 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_mbuftrace.h"
|
||||
@ -182,8 +182,9 @@ sysctl_net_mpls_setup(struct sysctllog **clog)
|
||||
|
||||
DOMAIN_DEFINE(mplsdomain);
|
||||
|
||||
PR_WRAP_USRREQ(mpls_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(mpls)
|
||||
#define mpls_attach mpls_attach_wrapper
|
||||
#define mpls_detach mpls_detach_wrapper
|
||||
#define mpls_usrreq mpls_usrreq_wrapper
|
||||
|
||||
static const struct pr_usrreqs mpls_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: natm.c,v 1.26 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: natm.c,v 1.27 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.26 2014/05/19 02:51:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.27 2014/05/20 19:04:00 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -396,8 +396,9 @@ m->m_pkthdr.rcvif = NULL; /* null it out to be safe */
|
||||
goto next;
|
||||
}
|
||||
|
||||
PR_WRAP_USRREQ(natm_usrreq)
|
||||
|
||||
PR_WRAP_USRREQS(natm)
|
||||
#define natm_attach natm_attach_wrapper
|
||||
#define natm_detach natm_detach_wrapper
|
||||
#define natm_usrreq natm_usrreq_wrapper
|
||||
|
||||
const struct pr_usrreqs natm_usrreqs = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: protosw.h,v 1.46 2014/05/19 02:51:25 rmind Exp $ */
|
||||
/* $NetBSD: protosw.h,v 1.47 2014/05/20 19:04:00 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
@ -270,14 +270,31 @@ void pfctlinput2(int, const struct sockaddr *, void *);
|
||||
*/
|
||||
#include <sys/systm.h> /* kernel_lock */
|
||||
|
||||
#define PR_WRAP_USRREQ(name) \
|
||||
#define PR_WRAP_USRREQS(name) \
|
||||
static int \
|
||||
name##_wrapper(struct socket *a, int b, struct mbuf *c, \
|
||||
struct mbuf *d, struct mbuf *e, struct lwp *f) \
|
||||
name##_attach_wrapper(struct socket *a, int b) \
|
||||
{ \
|
||||
int rv; \
|
||||
KERNEL_LOCK(1, NULL); \
|
||||
rv = name(a, b, c, d, e, f); \
|
||||
rv = name##_attach(a, b); \
|
||||
KERNEL_UNLOCK_ONE(NULL); \
|
||||
return rv; \
|
||||
} \
|
||||
static void \
|
||||
name##_detach_wrapper(struct socket *a) \
|
||||
{ \
|
||||
KERNEL_LOCK(1, NULL); \
|
||||
name##_detach(a); \
|
||||
KERNEL_UNLOCK_ONE(NULL); \
|
||||
} \
|
||||
static int \
|
||||
name##_usrreq_wrapper(struct socket *a, int b, \
|
||||
struct mbuf *c, struct mbuf *d, struct mbuf *e, \
|
||||
struct lwp *f) \
|
||||
{ \
|
||||
int rv; \
|
||||
KERNEL_LOCK(1, NULL); \
|
||||
rv = name##_usrreq(a, b, c, d, e, f); \
|
||||
KERNEL_UNLOCK_ONE(NULL); \
|
||||
return rv; \
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user