IPv4 multicast: fix netstat -g
The vif structure includes fields at the end which are #ifdef KERNEL, causing a mismatch between the structure sizes between kernel and user level. netstat -g failed with an ENOMEM on the sysctl to fetch the vif table. Change the vif sysctl code in ip_mroute to copy out only the user-level-visible portion of each table entry. Reviewed by: bz, wma Differential Revision: https://reviews.freebsd.org/D34627
This commit is contained in:
parent
2cf1e120c6
commit
04cd74b4cd
@ -2727,18 +2727,23 @@ static SYSCTL_NODE(_net_inet_ip, OID_AUTO, mfctable,
|
||||
static int
|
||||
sysctl_viflist(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
int error, i;
|
||||
|
||||
if (req->newptr)
|
||||
return (EPERM);
|
||||
if (V_viftable == NULL) /* XXX unlocked */
|
||||
return (0);
|
||||
error = sysctl_wire_old_buffer(req, sizeof(*V_viftable) * MAXVIFS);
|
||||
error = sysctl_wire_old_buffer(req, MROUTE_VIF_SYSCTL_LEN * MAXVIFS);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
MRW_RLOCK();
|
||||
error = SYSCTL_OUT(req, V_viftable, sizeof(*V_viftable) * MAXVIFS);
|
||||
/* Copy out user-visible portion of vif entry. */
|
||||
for (i = 0; i < MAXVIFS; i++) {
|
||||
error = SYSCTL_OUT(req, &V_viftable[i], MROUTE_VIF_SYSCTL_LEN);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
MRW_RUNLOCK();
|
||||
return (error);
|
||||
}
|
||||
|
@ -265,6 +265,7 @@ struct vif {
|
||||
u_long v_bytes_in; /* # bytes in on interface */
|
||||
u_long v_bytes_out; /* # bytes out on interface */
|
||||
#ifdef _KERNEL
|
||||
#define MROUTE_VIF_SYSCTL_LEN __offsetof(struct vif, v_spin)
|
||||
struct mtx v_spin; /* Spin mutex for pkt stats */
|
||||
char v_spin_name[32];
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user