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-head mailing list