Date: Sun, 14 Jun 2009 03:59:00 +0000 (UTC) From: Stef Walter <stef-list@memberwebs.com> To: "freebsd-net@FreeBSD.org" <freebsd-net@freebsd.org> Subject: 32 bit compatibility for getifaddrs() Message-ID: <20090614035859.A057517056D@mx.npubs.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------080508060506040100070903 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit I've started running 64-bit FreeBSD (version 7.2) in production. I have a lot of old 6.3 32-bit jails I need to run as is for now. One problem I ran into is 32-bit getifaddrs() would crash accessing a 64-bit kernel via the sysctl NET_RT_IFLIST method. Attached is a patch that adds 32-bit compatibility to the rtsock.c route messages. Who would I work with to get this (or something like it) committed? Cheers, Stef --------------080508060506040100070903 Content-Type: text/x-diff; name="getifaddrs-rtsock-compat32.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="getifaddrs-rtsock-compat32.patch" --- sys/net/rtsock.c.orig 2009-06-13 19:51:29.000000000 +0000 +++ sys/net/rtsock.c 2009-06-13 20:44:35.000000000 +0000 @@ -1199,6 +1199,251 @@ netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */ } +#ifdef SCTL_MASK32 + +/* 32-bit structure definitions */ +struct timeval32 { + int32_t tv_sec; + int32_t tv_usec; +}; + +struct if_data32 { + u_int8_t ifi_type; + u_int8_t ifi_physical; + u_int8_t ifi_addrlen; + u_int8_t ifi_hdrlen; + u_int8_t ifi_link_state; + u_int8_t ifi_recvquota; + u_int8_t ifi_xmitquota; + u_int8_t ifi_datalen; + u_int32_t ifi_mtu; + u_int32_t ifi_metric; + u_int32_t ifi_baudrate; + u_int32_t ifi_ipackets; + u_int32_t ifi_ierrors; + u_int32_t ifi_opackets; + u_int32_t ifi_oerrors; + u_int32_t ifi_collisions; + u_int32_t ifi_ibytes; + u_int32_t ifi_obytes; + u_int32_t ifi_imcasts; + u_int32_t ifi_omcasts; + u_int32_t ifi_iqdrops; + u_int32_t ifi_noproto; + u_int32_t ifi_hwassist; + int32_t ifi_epoch; + struct timeval32 ifi_lastchange; +}; + +struct rt_metrics32 { + u_int32_t rmx_locks; + u_int32_t rmx_mtu; + u_int32_t rmx_hopcount; + u_int32_t rmx_expire; + u_int32_t rmx_recvpipe; + u_int32_t rmx_sendpipe; + u_int32_t rmx_ssthresh; + u_int32_t rmx_rtt; + u_int32_t rmx_rttvar; + u_int32_t rmx_pksent; + u_int32_t rmx_filler[4]; +}; + +struct rt_msghdr32 { + u_int16_t rtm_msglen; + u_int8_t rtm_version; + u_int8_t rtm_type; + u_int16_t rtm_index; + int32_t rtm_flags; + int32_t rtm_addrs; + int32_t rtm_pid; + int32_t rtm_seq; + int32_t rtm_errno; + int32_t rtm_fmask; + u_int32_t rtm_inits; + struct rt_metrics32 rtm_rmx; +}; + +struct if_msghdr32 { + u_int16_t ifm_msglen; + u_int8_t ifm_version; + u_int8_t ifm_type; + int32_t ifm_addrs; + int32_t ifm_flags; + u_int16_t ifm_index; + struct if_data32 ifm_data; +}; + +struct ifa_msghdr32 { + u_int16_t ifam_msglen; + u_int8_t ifam_version; + u_int8_t ifam_type; + int32_t ifam_addrs; + int32_t ifam_flags; + u_int16_t ifam_index; + int32_t ifam_metric; +}; + +struct ifma_msghdr32 { + u_int16_t ifmam_msglen; + u_int8_t ifmam_version; + u_int8_t ifmam_type; + int32_t ifmam_addrs; + int32_t ifmam_flags; + u_int16_t ifmam_index; +}; + +struct if_announcemsghdr32 { + u_int16_t ifan_msglen; + u_int8_t ifan_version; + u_int8_t ifan_type; + u_int16_t ifan_index; + char ifan_name[IFNAMSIZ]; + u_int16_t ifan_what; +}; + +#endif + +/* + * Output route message to sysctl for 64 or 32-bit + */ +static int +rt_sysctl_out(struct sysctl_req *req, const void *data, size_t len) +{ + const struct rt_msghdr *rtm = data; + int error; + +#ifdef SCTL_MASK32 + if (req->flags & SCTL_MASK32) { + switch (rtm->rtm_type) { + case RTM_IFINFO: + { + const struct if_msghdr *ifm = data; + struct if_msghdr32 ifm32; + data = ((const u_char*)data) + sizeof (*ifm); + len -= sizeof (*ifm); + ifm32.ifm_msglen = sizeof (ifm32) + len; + ifm32.ifm_version = ifm->ifm_version; + ifm32.ifm_type = ifm->ifm_type; + ifm32.ifm_addrs = ifm->ifm_addrs; + ifm32.ifm_flags = ifm->ifm_flags; + ifm32.ifm_index = ifm->ifm_index; + ifm32.ifm_data.ifi_type = ifm->ifm_data.ifi_type; + ifm32.ifm_data.ifi_physical = ifm->ifm_data.ifi_physical; + ifm32.ifm_data.ifi_addrlen = ifm->ifm_data.ifi_addrlen; + ifm32.ifm_data.ifi_hdrlen = ifm->ifm_data.ifi_hdrlen; + ifm32.ifm_data.ifi_link_state = ifm->ifm_data.ifi_link_state; + ifm32.ifm_data.ifi_recvquota = 0; + ifm32.ifm_data.ifi_xmitquota = 0; + ifm32.ifm_data.ifi_datalen = ifm->ifm_data.ifi_datalen; + ifm32.ifm_data.ifi_mtu = ifm->ifm_data.ifi_mtu; + ifm32.ifm_data.ifi_metric = ifm->ifm_data.ifi_metric; + ifm32.ifm_data.ifi_baudrate = ifm->ifm_data.ifi_baudrate; + ifm32.ifm_data.ifi_ipackets = ifm->ifm_data.ifi_ipackets; + ifm32.ifm_data.ifi_ierrors = ifm->ifm_data.ifi_ierrors; + ifm32.ifm_data.ifi_opackets = ifm->ifm_data.ifi_opackets; + ifm32.ifm_data.ifi_oerrors = ifm->ifm_data.ifi_oerrors; + ifm32.ifm_data.ifi_collisions = ifm->ifm_data.ifi_collisions; + ifm32.ifm_data.ifi_ibytes = ifm->ifm_data.ifi_ibytes; + ifm32.ifm_data.ifi_obytes = ifm->ifm_data.ifi_obytes; + ifm32.ifm_data.ifi_imcasts = ifm->ifm_data.ifi_imcasts; + ifm32.ifm_data.ifi_omcasts = ifm->ifm_data.ifi_omcasts; + ifm32.ifm_data.ifi_iqdrops = ifm->ifm_data.ifi_iqdrops; + ifm32.ifm_data.ifi_noproto = ifm->ifm_data.ifi_noproto; + ifm32.ifm_data.ifi_hwassist = ifm->ifm_data.ifi_hwassist; + ifm32.ifm_data.ifi_epoch = ifm->ifm_data.ifi_epoch; + ifm32.ifm_data.ifi_lastchange.tv_sec = ifm->ifm_data.ifi_lastchange.tv_sec; + ifm32.ifm_data.ifi_lastchange.tv_usec = ifm->ifm_data.ifi_lastchange.tv_usec; + error = SYSCTL_OUT(req, &ifm32, sizeof (ifm32)); + break; + } + case RTM_NEWADDR: + case RTM_DELADDR: + { + const struct ifa_msghdr *ifam = data; + struct ifa_msghdr32 ifam32; + data = ((const u_char*)data) + sizeof (*ifam); + len -= sizeof (*ifam); + ifam32.ifam_msglen = sizeof (ifam32) + len; + ifam32.ifam_version = ifam->ifam_version; + ifam32.ifam_type = ifam->ifam_type; + ifam32.ifam_addrs = ifam->ifam_addrs; + ifam32.ifam_flags = ifam->ifam_flags; + ifam32.ifam_index = ifam->ifam_index; + ifam32.ifam_metric = ifam->ifam_metric; + error = SYSCTL_OUT(req, &ifam32, sizeof (ifam32)); + break; + } + case RTM_NEWMADDR: + case RTM_DELMADDR: + { + const struct ifma_msghdr *ifmam = data; + struct ifma_msghdr32 ifmam32; + data = ((const u_char*)data) + sizeof (*ifmam); + len -= sizeof (*ifmam); + ifmam32.ifmam_msglen = sizeof (ifmam32) + len; + ifmam32.ifmam_version = ifmam->ifmam_version; + ifmam32.ifmam_type = ifmam->ifmam_type; + ifmam32.ifmam_addrs = ifmam->ifmam_addrs; + ifmam32.ifmam_flags = ifmam->ifmam_flags; + ifmam32.ifmam_index = ifmam->ifmam_index; + error = SYSCTL_OUT(req, &ifmam32, sizeof (ifmam32)); + break; + } + case RTM_IFANNOUNCE: + { + const struct if_announcemsghdr *ifan = data; + struct if_announcemsghdr32 ifan32; + data = ((const u_char*)data) + sizeof (*ifan); + len -= sizeof (*ifan); + ifan32.ifan_msglen = sizeof (ifan32) + len; + ifan32.ifan_version = ifan->ifan_version; + ifan32.ifan_type = ifan->ifan_type; + ifan32.ifan_index = ifan->ifan_index; + bcopy(&ifan->ifan_name, &ifan32.ifan_name, sizeof (ifan32.ifan_name)); + ifan32.ifan_what = ifan->ifan_what; + error = SYSCTL_OUT(req, &ifan32, sizeof (ifan32)); + break; + } + default: + { + struct rt_msghdr32 rtm32; + data = ((const u_char*)data) + sizeof (*rtm); + len -= sizeof (*rtm); + rtm32.rtm_msglen = sizeof (rtm32) + len; + rtm32.rtm_version = rtm->rtm_version; + rtm32.rtm_type = rtm->rtm_type; + rtm32.rtm_index = rtm->rtm_index; + rtm32.rtm_flags = rtm->rtm_flags; + rtm32.rtm_addrs = rtm->rtm_addrs; + rtm32.rtm_pid = rtm->rtm_pid; + rtm32.rtm_seq = rtm->rtm_seq; + rtm32.rtm_errno = rtm->rtm_errno; + rtm32.rtm_use = rtm->rtm_use; + rtm32.rtm_inits = rtm->rtm_inits; + rtm32.rtm_rmx.rmx_locks = rtm->rtm_rmx.rmx_locks; + rtm32.rtm_rmx.rmx_mtu = rtm->rtm_rmx.rmx_mtu; + rtm32.rtm_rmx.rmx_hopcount = rtm->rtm_rmx.rmx_hopcount; + rtm32.rtm_rmx.rmx_expire = rtm->rtm_rmx.rmx_expire; + rtm32.rtm_rmx.rmx_recvpipe = rtm->rtm_rmx.rmx_recvpipe; + rtm32.rtm_rmx.rmx_sendpipe = rtm->rtm_rmx.rmx_sendpipe; + rtm32.rtm_rmx.rmx_ssthresh = rtm->rtm_rmx.rmx_ssthresh; + rtm32.rtm_rmx.rmx_rtt = rtm->rtm_rmx.rmx_rtt; + rtm32.rtm_rmx.rmx_rttvar = rtm->rtm_rmx.rmx_rttvar; + rtm32.rtm_rmx.rmx_pksent = rtm->rtm_rmx.rmx_pksent; + error = SYSCTL_OUT(req, &rtm32, sizeof (rtm32)); + break; + } + } + + if (error) + return error; + } +#endif /* SCTL_MASK32 */ + error = SYSCTL_OUT(req, data, len); + return error; +} + /* * This is used in dumping the kernel table via sysctl(). */ @@ -1237,7 +1482,7 @@ rtm->rtm_index = rt->rt_ifp->if_index; rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; rtm->rtm_addrs = info.rti_addrs; - error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); + error = rt_sysctl_out(w->w_req, (caddr_t)rtm, size); return (error); } return (error); @@ -1268,7 +1513,7 @@ ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; ifm->ifm_data = ifp->if_data; ifm->ifm_addrs = info.rti_addrs; - error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); + error = rt_sysctl_out(w->w_req,(caddr_t)ifm, len); if (error) goto done; } @@ -1290,7 +1535,7 @@ ifam->ifam_flags = ifa->ifa_flags; ifam->ifam_metric = ifa->ifa_metric; ifam->ifam_addrs = info.rti_addrs; - error = SYSCTL_OUT(w->w_req, w->w_tmem, len); + error = rt_sysctl_out(w->w_req, w->w_tmem, len); if (error) goto done; } @@ -1338,7 +1583,7 @@ ifmam->ifmam_index = ifma->ifma_ifp->if_index; ifmam->ifmam_flags = 0; ifmam->ifmam_addrs = info.rti_addrs; - error = SYSCTL_OUT(w->w_req, w->w_tmem, len); + error = rt_sysctl_out(w->w_req, w->w_tmem, len); if (error) { IF_ADDR_UNLOCK(ifp); goto done; --------------080508060506040100070903--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090614035859.A057517056D>