svn commit: r332493 - stable/11/sys/net
Brooks Davis
brooks at FreeBSD.org
Fri Apr 13 22:32:29 UTC 2018
Author: brooks
Date: Fri Apr 13 22:32:28 2018
New Revision: 332493
URL: https://svnweb.freebsd.org/changeset/base/332493
Log:
MFC r332088:
Add 32-bit compat for ioctls that take struct ifgroupreq.
Use an accessor to access ifgr_group and ifgr_groups.
Use an macro CASE_IOC_IFGROUPREQ(cmd) in place of case statements such
as "case SIOCAIFGROUP:". This avoids poluting the switch statements
with large numbers of #ifdefs.
Reviewed by: kib
Obtained from: CheriBSD
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D14960
Modified:
stable/11/sys/net/if.c
stable/11/sys/net/if.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/net/if.c
==============================================================================
--- stable/11/sys/net/if.c Fri Apr 13 21:19:06 2018 (r332492)
+++ stable/11/sys/net/if.c Fri Apr 13 22:32:28 2018 (r332493)
@@ -133,8 +133,25 @@ struct ifreq32 {
CTASSERT(sizeof(struct ifreq) == sizeof(struct ifreq32));
CTASSERT(__offsetof(struct ifreq, ifr_ifru) ==
__offsetof(struct ifreq32, ifr_ifru));
-#endif
+struct ifgroupreq32 {
+ char ifgr_name[IFNAMSIZ];
+ u_int ifgr_len;
+ union {
+ char ifgru_group[IFNAMSIZ];
+ uint32_t ifgru_groups;
+ } ifgr_ifgru;
+};
+#define _CASE_IOC_IFGROUPREQ_32(cmd) \
+ case _IOC_NEWTYPE((cmd), struct ifgroupreq32):
+#else
+#define _CASE_IOC_IFGROUPREQ_32(cmd)
+#endif /* COMPAT_FREEBSD32 */
+
+#define CASE_IOC_IFGROUPREQ(cmd) \
+ _CASE_IOC_IFGROUPREQ_32(cmd) \
+ case (cmd)
+
union ifreq_union {
struct ifreq ifr;
#ifdef COMPAT_FREEBSD32
@@ -142,6 +159,13 @@ union ifreq_union {
#endif
};
+union ifgroupreq_union {
+ struct ifgroupreq ifgr;
+#ifdef COMPAT_FREEBSD32
+ struct ifgroupreq32 ifgr32;
+#endif
+};
+
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
@@ -1490,17 +1514,42 @@ if_delgroups(struct ifnet *ifp)
IFNET_WUNLOCK();
}
+static char *
+ifgr_group_get(void *ifgrp)
+{
+ union ifgroupreq_union *ifgrup;
+
+ ifgrup = ifgrp;
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32))
+ return (&ifgrup->ifgr32.ifgr_ifgru.ifgru_group[0]);
+#endif
+ return (&ifgrup->ifgr.ifgr_ifgru.ifgru_group[0]);
+}
+
+static struct ifg_req *
+ifgr_groups_get(void *ifgrp)
+{
+ union ifgroupreq_union *ifgrup;
+
+ ifgrup = ifgrp;
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32))
+ return ((struct ifg_req *)(uintptr_t)
+ ifgrup->ifgr32.ifgr_ifgru.ifgru_groups);
+#endif
+ return (ifgrup->ifgr.ifgr_ifgru.ifgru_groups);
+}
+
/*
- * Stores all groups from an interface in memory pointed
- * to by data
+ * Stores all groups from an interface in memory pointed to by ifgr.
*/
static int
-if_getgroup(struct ifgroupreq *data, struct ifnet *ifp)
+if_getgroup(struct ifgroupreq *ifgr, struct ifnet *ifp)
{
int len, error;
struct ifg_list *ifgl;
struct ifg_req ifgrq, *ifgp;
- struct ifgroupreq *ifgr = data;
if (ifgr->ifgr_len == 0) {
IF_ADDR_RLOCK(ifp);
@@ -1511,7 +1560,7 @@ if_getgroup(struct ifgroupreq *data, struct ifnet *ifp
}
len = ifgr->ifgr_len;
- ifgp = ifgr->ifgr_groups;
+ ifgp = ifgr_groups_get(ifgr);
/* XXX: wire */
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
@@ -1535,12 +1584,11 @@ if_getgroup(struct ifgroupreq *data, struct ifnet *ifp
}
/*
- * Stores all members of a group in memory pointed to by data
+ * Stores all members of a group in memory pointed to by igfr
*/
static int
-if_getgroupmembers(struct ifgroupreq *data)
+if_getgroupmembers(struct ifgroupreq *ifgr)
{
- struct ifgroupreq *ifgr = data;
struct ifg_group *ifg;
struct ifg_member *ifgm;
struct ifg_req ifgrq, *ifgp;
@@ -1563,7 +1611,7 @@ if_getgroupmembers(struct ifgroupreq *data)
}
len = ifgr->ifgr_len;
- ifgp = ifgr->ifgr_groups;
+ ifgp = ifgr_groups_get(ifgr);
TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
if (len < sizeof(ifgrq)) {
IFNET_RUNLOCK();
@@ -2793,34 +2841,28 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data,
error = if_gethwaddr(ifp, ifr);
break;
- case SIOCAIFGROUP:
- {
- struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
-
+ CASE_IOC_IFGROUPREQ(SIOCAIFGROUP):
error = priv_check(td, PRIV_NET_ADDIFGROUP);
if (error)
return (error);
- if ((error = if_addgroup(ifp, ifgr->ifgr_group)))
+ if ((error = if_addgroup(ifp,
+ ifgr_group_get((struct ifgroupreq *)data))))
return (error);
break;
- }
- case SIOCGIFGROUP:
- if ((error = if_getgroup((struct ifgroupreq *)ifr, ifp)))
+ CASE_IOC_IFGROUPREQ(SIOCGIFGROUP):
+ if ((error = if_getgroup((struct ifgroupreq *)data, ifp)))
return (error);
break;
- case SIOCDIFGROUP:
- {
- struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
-
+ CASE_IOC_IFGROUPREQ(SIOCDIFGROUP):
error = priv_check(td, PRIV_NET_DELIFGROUP);
if (error)
return (error);
- if ((error = if_delgroup(ifp, ifgr->ifgr_group)))
+ if ((error = if_delgroup(ifp,
+ ifgr_group_get((struct ifgroupreq *)data))))
return (error);
break;
- }
default:
error = ENOIOCTL;
@@ -2926,7 +2968,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, s
error = if_clone_list((struct if_clonereq *)data);
CURVNET_RESTORE();
return (error);
- case SIOCGIFGMEMB:
+ CASE_IOC_IFGROUPREQ(SIOCGIFGMEMB):
error = if_getgroupmembers((struct ifgroupreq *)data);
CURVNET_RESTORE();
return (error);
Modified: stable/11/sys/net/if.h
==============================================================================
--- stable/11/sys/net/if.h Fri Apr 13 21:19:06 2018 (r332492)
+++ stable/11/sys/net/if.h Fri Apr 13 22:32:28 2018 (r332493)
@@ -512,8 +512,10 @@ struct ifgroupreq {
char ifgru_group[IFNAMSIZ];
struct ifg_req *ifgru_groups;
} ifgr_ifgru;
+#ifndef _KERNEL
#define ifgr_group ifgr_ifgru.ifgru_group
#define ifgr_groups ifgr_ifgru.ifgru_groups
+#endif
};
/*
More information about the svn-src-stable-11
mailing list