Author: brooks Date: Thu Apr 5 22:14:55 2018 New Revision: 332088 URL: https://svnweb.freebsd.org/changeset/base/332088
Log: 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 MFC after: 1 week Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D14960 Modified: head/sys/net/if.c head/sys/net/if.h Modified: head/sys/net/if.c ============================================================================== --- head/sys/net/if.c Thu Apr 5 21:58:28 2018 (r332087) +++ head/sys/net/if.c Thu Apr 5 22:14:55 2018 (r332088) @@ -142,8 +142,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 @@ -151,6 +168,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"); @@ -1500,17 +1524,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); @@ -1521,7 +1570,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) { @@ -1545,12 +1594,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; @@ -1573,7 +1621,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(); @@ -2803,34 +2851,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; @@ -2932,7 +2974,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: head/sys/net/if.h ============================================================================== --- head/sys/net/if.h Thu Apr 5 21:58:28 2018 (r332087) +++ head/sys/net/if.h Thu Apr 5 22:14:55 2018 (r332088) @@ -517,8 +517,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 }; /* _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"