From owner-freebsd-net@FreeBSD.ORG Sun Jun 14 04:28:51 2009 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 46734106566C for ; Sun, 14 Jun 2009 04:28:51 +0000 (UTC) (envelope-from stef-list@memberwebs.com) Received: from mx.npubs.com (mail.npubs.com [94.75.203.100]) by mx1.freebsd.org (Postfix) with ESMTP id C74ED8FC0A for ; Sun, 14 Jun 2009 04:28:50 +0000 (UTC) (envelope-from stef-list@memberwebs.com) Received: from mx.npubs.com (avhost [94.75.203.103]) by mx.npubs.com (Postfix) with ESMTP id BCD2617057C for ; Sun, 14 Jun 2009 03:59:00 +0000 (UTC) Received: from sqlserver1 (unknown [74.82.45.12]) by mx.npubs.com (Postfix) with ESMTP id A057517056D for ; Sun, 14 Jun 2009 03:58:59 +0000 (UTC) From: Stef Walter User-Agent: Thunderbird 2.0.0.21 (X11/20090409) MIME-Version: 1.0 To: "freebsd-net@FreeBSD.org" Content-Type: multipart/mixed; boundary="------------080508060506040100070903" Message-Id: <20090614035859.A057517056D@mx.npubs.com> X-Virus-Scanned: ClamAV using ClamSMTP Date: Sun, 14 Jun 2009 03:59:00 +0000 (UTC) Subject: 32 bit compatibility for getifaddrs() X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: stef@memberwebs.com List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Jun 2009 04:28:51 -0000 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--