svn commit: r231505 - in head: lib/libc/gen sys/net sys/sys
Sergey Kandaurov
pluknet at freebsd.org
Thu Oct 10 15:44:27 UTC 2013
On 11 February 2012 10:02, Bjoern A. Zeeb <bz at freebsd.org> wrote:
> Author: bz
> Date: Sat Feb 11 06:02:16 2012
> New Revision: 231505
> URL: http://svn.freebsd.org/changeset/base/231505
>
> Log:
> Introduce a new NET_RT_IFLISTL API to query the address list. It works
> on extended and extensible structs if_msghdrl and ifa_msghdrl. This
> will allow us to extend both the msghdrl structs and eventually if_data
> in the future without breaking the ABI.
There is some inconsistency between native and compat32 binaries wrt
NET_RT_IFLISTL. I didn't investigate how it may affect userland utilities.
[My limited debugging said me it does not.]
> static int
> +sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
> + struct walkarg *w, int len)
> +{
> + struct if_msghdrl *ifm;
> +
> +#ifdef COMPAT_FREEBSD32
> + if (w->w_req->flags & SCTL_MASK32) {
> + struct if_msghdrl32 *ifm32;
> +
> + ifm32 = (struct if_msghdrl32 *)w->w_tmem;
> + ifm32->ifm_addrs = info->rti_addrs;
> + ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
> + ifm32->ifm_index = ifp->if_index;
> + ifm32->_ifm_spare1 = 0;
> + ifm32->ifm_len = sizeof(*ifm32);
> + ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
> +
> + copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifm32->ifm_data.ifi_vhid =
> + (*carp_get_vhid_p)(ifp->if_addr);
> +
> + return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
> + }
> +#endif
> + ifm = (struct if_msghdrl *)w->w_tmem;
> + ifm->ifm_addrs = info->rti_addrs;
> + ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
> + ifm->ifm_index = ifp->if_index;
> + ifm->_ifm_spare1 = 0;
> + ifm->ifm_len = sizeof(*ifm);
> + ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
> +
> + ifm->ifm_data = ifp->if_data;
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
> +
> + return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
> +}
This function consistently uses ifp->if_data to fill ifm_data.
But please see below.
> +
> +static int
> +sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
> + struct walkarg *w, int len)
> +{
> + struct if_msghdr *ifm;
> +
> +#ifdef COMPAT_FREEBSD32
> + if (w->w_req->flags & SCTL_MASK32) {
> + struct if_msghdr32 *ifm32;
> +
> + ifm32 = (struct if_msghdr32 *)w->w_tmem;
> + ifm32->ifm_addrs = info->rti_addrs;
> + ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
> + ifm32->ifm_index = ifp->if_index;
> +
> + copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifm32->ifm_data.ifi_vhid =
> + (*carp_get_vhid_p)(ifp->if_addr);
> +
> + return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
> + }
> +#endif
> + ifm = (struct if_msghdr *)w->w_tmem;
> + ifm->ifm_addrs = info->rti_addrs;
> + ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
> + ifm->ifm_index = ifp->if_index;
> +
> + ifm->ifm_data = ifp->if_data;
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
> +
> + return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
> +}
Ditto.
> +
> +static int
> +sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info,
> + struct walkarg *w, int len)
> +{
> + struct ifa_msghdrl *ifam;
> +
> +#ifdef COMPAT_FREEBSD32
> + if (w->w_req->flags & SCTL_MASK32) {
> + struct ifa_msghdrl32 *ifam32;
> +
> + ifam32 = (struct ifa_msghdrl32 *)w->w_tmem;
> + ifam32->ifam_addrs = info->rti_addrs;
> + ifam32->ifam_flags = ifa->ifa_flags;
> + ifam32->ifam_index = ifa->ifa_ifp->if_index;
> + ifam32->_ifam_spare1 = 0;
> + ifam32->ifam_len = sizeof(*ifam32);
> + ifam32->ifam_data_off =
> + offsetof(struct ifa_msghdrl32, ifam_data);
> + ifam32->ifam_metric = ifa->ifa_metric;
> +
> + copy_ifdata32(&ifa->ifa_ifp->if_data, &ifam32->ifam_data);
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifam32->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa);
> +
> + return (SYSCTL_OUT(w->w_req, (caddr_t)ifam32, len));
> + }
> +#endif
> +
> + ifam = (struct ifa_msghdrl *)w->w_tmem;
> + ifam->ifam_addrs = info->rti_addrs;
> + ifam->ifam_flags = ifa->ifa_flags;
> + ifam->ifam_index = ifa->ifa_ifp->if_index;
> + ifam->_ifam_spare1 = 0;
> + ifam->ifam_len = sizeof(*ifam);
> + ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data);
> + ifam->ifam_metric = ifa->ifa_metric;
> +
> + ifam->ifam_data = ifa->if_data;
> + /* Fixup if_data carp(4) vhid. */
> + if (carp_get_vhid_p != NULL)
> + ifam->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa);
> +
> + return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
> +}
This function uses ifa->if_data to fill ifam_data for native binaries,
and ifa->ifa_ifp->if_data for compat32. AFAIK they may not match.
--
wbr,
pluknet
More information about the svn-src-all
mailing list