Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/refcount.h> | #include <sys/refcount.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sockio.h> | #include <sys/sockio.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/sysent.h> | |||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <machine/stdarg.h> | #include <machine/stdarg.h> | ||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
Show All 26 Lines | |||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
#endif /* INET || INET6 */ | #endif /* INET || INET6 */ | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <compat/freebsd32/freebsd32.h> | #include <compat/freebsd32/freebsd32.h> | ||||
struct ifreq_buffer32 { | |||||
uint32_t length; /* (size_t) */ | |||||
uint32_t buffer; /* (void *) */ | |||||
}; | |||||
/* | |||||
* Interface request structure used for socket | |||||
* ioctl's. All interface ioctl's must have parameter | |||||
* definitions which begin with ifr_name. The | |||||
* remainder may be interface specific. | |||||
*/ | |||||
struct ifreq32 { | |||||
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ | |||||
union { | |||||
struct sockaddr ifru_addr; | |||||
struct sockaddr ifru_dstaddr; | |||||
struct sockaddr ifru_broadaddr; | |||||
struct ifreq_buffer32 ifru_buffer; | |||||
short ifru_flags[2]; | |||||
short ifru_index; | |||||
int ifru_jid; | |||||
int ifru_metric; | |||||
int ifru_mtu; | |||||
int ifru_phys; | |||||
int ifru_media; | |||||
uint32_t ifru_data; | |||||
int ifru_cap[2]; | |||||
u_int ifru_fib; | |||||
u_char ifru_vlan_pcp; | |||||
} ifr_ifru; | |||||
}; | |||||
CTASSERT(sizeof(struct ifreq) == sizeof(struct ifreq32)); | |||||
CTASSERT(__offsetof(struct ifreq, ifr_ifru) == | |||||
__offsetof(struct ifreq32, ifr_ifru)); | |||||
#endif | #endif | ||||
union ifreq_union { | |||||
struct ifreq ifr; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
struct ifreq32 ifr32; | |||||
#endif | |||||
}; | |||||
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); | SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); | ||||
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); | SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); | ||||
SYSCTL_INT(_net_link, OID_AUTO, ifqmaxlen, CTLFLAG_RDTUN, | SYSCTL_INT(_net_link, OID_AUTO, ifqmaxlen, CTLFLAG_RDTUN, | ||||
&ifqmaxlen, 0, "max send queue size"); | &ifqmaxlen, 0, "max send queue size"); | ||||
/* Log link state change events */ | /* Log link state change events */ | ||||
static int log_link_state_change = 1; | static int log_link_state_change = 1; | ||||
▲ Show 20 Lines • Show All 2,187 Lines • ▼ Show 20 Lines | ifunit(const char *name) | ||||
TAILQ_FOREACH(ifp, &V_ifnet, if_link) { | TAILQ_FOREACH(ifp, &V_ifnet, if_link) { | ||||
if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0) | if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0) | ||||
break; | break; | ||||
} | } | ||||
IFNET_RUNLOCK_NOSLEEP(); | IFNET_RUNLOCK_NOSLEEP(); | ||||
return (ifp); | return (ifp); | ||||
} | } | ||||
static void * | |||||
ifr_buffer_get_buffer(struct thread *td, void *data) | |||||
{ | |||||
union ifreq_union *ifrup; | |||||
kib: Does it make sense to provide a stand-alone definition of this union and use it in all… | |||||
ifrup = data; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) | |||||
return ((void *)(uintptr_t) | |||||
ifrup->ifr32.ifr_ifru.ifru_buffer.buffer); | |||||
#endif | |||||
return (ifrup->ifr.ifr_ifru.ifru_buffer.buffer); | |||||
} | |||||
static void | |||||
ifr_buffer_set_buffer_null(struct thread *td, void *data) | |||||
Not Done Inline Actions'else' is not needed there and in all subsequent #ifdefs with returns. Then you can un-indent the unconditionally-compiled line. kib: 'else' is not needed there and in all subsequent #ifdefs with returns. Then you can un-indent… | |||||
{ | |||||
union ifreq_union *ifrup; | |||||
ifrup = data; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) | |||||
ifrup->ifr32.ifr_ifru.ifru_buffer.buffer = 0; | |||||
else | |||||
#endif | |||||
ifrup->ifr.ifr_ifru.ifru_buffer.buffer = NULL; | |||||
} | |||||
static size_t | |||||
ifr_buffer_get_length(struct thread *td, void *data) | |||||
{ | |||||
Not Done Inline ActionsThen why the argument is needed ? kib: Then why the argument is needed ? | |||||
union ifreq_union *ifrup; | |||||
ifrup = data; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) | |||||
return (ifrup->ifr32.ifr_ifru.ifru_buffer.length); | |||||
#endif | |||||
return (ifrup->ifr.ifr_ifru.ifru_buffer.length); | |||||
} | |||||
static void | |||||
ifr_buffer_set_length(struct thread *td, void *data, size_t len) | |||||
{ | |||||
union ifreq_union *ifrup; | |||||
ifrup = data; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) | |||||
ifrup->ifr32.ifr_ifru.ifru_buffer.length = len; | |||||
else | |||||
#endif | |||||
ifrup->ifr.ifr_ifru.ifru_buffer.length = len; | |||||
} | |||||
/* | /* | ||||
* Hardware specific interface ioctls. | * Hardware specific interface ioctls. | ||||
*/ | */ | ||||
static int | static int | ||||
ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) | ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) | ||||
{ | { | ||||
struct ifreq *ifr; | struct ifreq *ifr; | ||||
int error = 0, do_ifup = 0; | int error = 0, do_ifup = 0; | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | #endif | ||||
case SIOCGIFDESCR: | case SIOCGIFDESCR: | ||||
error = 0; | error = 0; | ||||
sx_slock(&ifdescr_sx); | sx_slock(&ifdescr_sx); | ||||
if (ifp->if_description == NULL) | if (ifp->if_description == NULL) | ||||
error = ENOMSG; | error = ENOMSG; | ||||
else { | else { | ||||
/* space for terminating nul */ | /* space for terminating nul */ | ||||
descrlen = strlen(ifp->if_description) + 1; | descrlen = strlen(ifp->if_description) + 1; | ||||
if (ifr->ifr_buffer.length < descrlen) | if (ifr_buffer_get_length(td, ifr) < descrlen) | ||||
ifr->ifr_buffer.buffer = NULL; | ifr_buffer_set_buffer_null(td, ifr); | ||||
else | else | ||||
error = copyout(ifp->if_description, | error = copyout(ifp->if_description, | ||||
ifr->ifr_buffer.buffer, descrlen); | ifr_buffer_get_buffer(td, ifr), descrlen); | ||||
ifr->ifr_buffer.length = descrlen; | ifr_buffer_set_length(td, ifr, descrlen); | ||||
} | } | ||||
sx_sunlock(&ifdescr_sx); | sx_sunlock(&ifdescr_sx); | ||||
break; | break; | ||||
case SIOCSIFDESCR: | case SIOCSIFDESCR: | ||||
error = priv_check(td, PRIV_NET_SETIFDESCR); | error = priv_check(td, PRIV_NET_SETIFDESCR); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Copy only (length-1) bytes to make sure that | * Copy only (length-1) bytes to make sure that | ||||
* if_description is always nul terminated. The | * if_description is always nul terminated. The | ||||
* length parameter is supposed to count the | * length parameter is supposed to count the | ||||
* terminating nul in. | * terminating nul in. | ||||
*/ | */ | ||||
if (ifr->ifr_buffer.length > ifdescr_maxlen) | if (ifr_buffer_get_length(td, ifr) > ifdescr_maxlen) | ||||
return (ENAMETOOLONG); | return (ENAMETOOLONG); | ||||
else if (ifr->ifr_buffer.length == 0) | else if (ifr_buffer_get_length(td, ifr) == 0) | ||||
descrbuf = NULL; | descrbuf = NULL; | ||||
else { | else { | ||||
descrbuf = malloc(ifr->ifr_buffer.length, M_IFDESCR, | descrbuf = malloc(ifr_buffer_get_length(td, ifr), | ||||
M_WAITOK | M_ZERO); | M_IFDESCR, M_WAITOK | M_ZERO); | ||||
error = copyin(ifr->ifr_buffer.buffer, descrbuf, | error = copyin(ifr_buffer_get_buffer(td, ifr), descrbuf, | ||||
ifr->ifr_buffer.length - 1); | ifr_buffer_get_length(td, ifr) - 1); | ||||
if (error) { | if (error) { | ||||
free(descrbuf, M_IFDESCR); | free(descrbuf, M_IFDESCR); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
sx_xlock(&ifdescr_sx); | sx_xlock(&ifdescr_sx); | ||||
odescrbuf = ifp->if_description; | odescrbuf = ifp->if_description; | ||||
▲ Show 20 Lines • Show All 1,833 Lines • Show Last 20 Lines |
Does it make sense to provide a stand-alone definition of this union and use it in all functions instead of repeating #ifdefs ?