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
[-- Attachment #1 --]
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
[-- Attachment #2 --]
--- 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090614035859.A057517056D>
