svn commit: r235651 - in stable/7: lib/libc/gen sys/net sys/sys
Bjoern A. Zeeb
bz at FreeBSD.org
Sat May 19 14:38:15 UTC 2012
Author: bz
Date: Sat May 19 14:38:14 2012
New Revision: 235651
URL: http://svn.freebsd.org/changeset/base/235651
Log:
MFC r231505,231520:
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.
The MFC is just to provide the new API to old stable branches to make
updating and if needed downgrading a lot easier for updates to 10.
Modified:
stable/7/lib/libc/gen/sysctl.3
stable/7/sys/net/if.h
stable/7/sys/net/rtsock.c
stable/7/sys/sys/socket.h
Directory Properties:
stable/7/lib/libc/ (props changed)
stable/7/sys/ (props changed)
Modified: stable/7/lib/libc/gen/sysctl.3
==============================================================================
--- stable/7/lib/libc/gen/sysctl.3 Sat May 19 14:32:47 2012 (r235650)
+++ stable/7/lib/libc/gen/sysctl.3 Sat May 19 14:38:14 2012 (r235651)
@@ -28,7 +28,7 @@
.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd April 25, 2010
+.Dd February 11, 2012
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -568,6 +568,7 @@ The fifth and sixth level names are as f
.It "NET_RT_DUMP None"
.It "NET_RT_IFLIST 0 or if_index"
.It "NET_RT_IFMALIST 0 or if_index"
+.It "NET_RT_IFLISTL 0 or if_index"
.El
.Pp
The
@@ -575,6 +576,19 @@ The
name returns information about multicast group memberships on all interfaces
if 0 is specified, or for the interface specified by
.Va if_index .
+.Pp
+The
+.Dv NET_RT_IFLISTL
+is like
+.Dv NET_RT_IFLIST ,
+just returning message header structs with additional fields allowing the
+interface to be extended without breaking binary compatibility.
+The
+.Dv NET_RT_IFLISTL
+uses 'l' versions of the message header structures:
+.Va struct if_msghdrl
+and
+.Va struct ifa_msghdrl .
.It Li PF_INET
Get or set various global information about the IPv4
(Internet Protocol version 4).
Modified: stable/7/sys/net/if.h
==============================================================================
--- stable/7/sys/net/if.h Sat May 19 14:32:47 2012 (r235650)
+++ stable/7/sys/net/if.h Sat May 19 14:38:14 2012 (r235651)
@@ -230,6 +230,7 @@ struct if_data {
/*
* Message format for use in obtaining information about interfaces
* from getkerninfo and the routing socket
+ * For the new, extensible interface see struct if_msghdrl below.
*/
struct if_msghdr {
u_short ifm_msglen; /* to skip over non-understood messages */
@@ -242,8 +243,34 @@ struct if_msghdr {
};
/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifm_data_off or within ifm_data. Both the if_msghdr and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct if_msghdrl given a pointer to struct if_msghdrl.
+ */
+#define IF_MSGHDRL_IFM_DATA(_l) \
+ (struct if_data *)((char *)(_l) + (_l)->ifm_data_off)
+#define IF_MSGHDRL_RTA(_l) \
+ (void *)((uintptr_t)(_l) + (_l)->ifm_len)
+struct if_msghdrl {
+ u_short ifm_msglen; /* to skip over non-understood messages */
+ u_char ifm_version; /* future binary compatibility */
+ u_char ifm_type; /* message type */
+ int ifm_addrs; /* like rtm_addrs */
+ int ifm_flags; /* value of if_flags */
+ u_short ifm_index; /* index for associated ifp */
+ u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */
+ u_short ifm_len; /* length of if_msghdrl incl. if_data */
+ u_short ifm_data_off; /* offset of if_data from beginning */
+ struct if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
* Message format for use in obtaining information about interface addresses
* from getkerninfo and the routing socket
+ * For the new, extensible interface see struct ifa_msghdrl below.
*/
struct ifa_msghdr {
u_short ifam_msglen; /* to skip over non-understood messages */
@@ -256,6 +283,33 @@ struct ifa_msghdr {
};
/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifam_metric or within ifam_data. Both the ifa_msghdrl and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct ifa_msghdrl given a pointer to struct ifa_msghdrl.
+ */
+#define IFA_MSGHDRL_IFAM_DATA(_l) \
+ (struct if_data *)((char *)(_l) + (_l)->ifam_data_off)
+#define IFA_MSGHDRL_RTA(_l) \
+ (void *)((uintptr_t)(_l) + (_l)->ifam_len)
+struct ifa_msghdrl {
+ u_short ifam_msglen; /* to skip over non-understood messages */
+ u_char ifam_version; /* future binary compatibility */
+ u_char ifam_type; /* message type */
+ int ifam_addrs; /* like rtm_addrs */
+ int ifam_flags; /* value of ifa_flags */
+ u_short ifam_index; /* index for associated ifp */
+ u_short _ifam_spare1; /* spare space to grow if_index, see if_var.h */
+ u_short ifam_len; /* length of ifa_msghdrl incl. if_data */
+ u_short ifam_data_off; /* offset of if_data from beginning */
+ int ifam_metric; /* value of ifa_metric */
+ struct if_data ifam_data;/* statistics and other data about if or
+ * address */
+};
+
+/*
* Message format for use in obtaining information about multicast addresses
* from the routing socket
*/
Modified: stable/7/sys/net/rtsock.c
==============================================================================
--- stable/7/sys/net/rtsock.c Sat May 19 14:32:47 2012 (r235650)
+++ stable/7/sys/net/rtsock.c Sat May 19 14:38:14 2012 (r235651)
@@ -62,6 +62,76 @@
extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
#endif /* SCTP */
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <compat/freebsd32/freebsd32.h>
+
+struct if_data32 {
+ uint8_t ifi_type;
+ uint8_t ifi_physical;
+ uint8_t ifi_addrlen;
+ uint8_t ifi_hdrlen;
+ uint8_t ifi_link_state;
+ uint8_t ifi_spare_char1;
+ uint8_t ifi_spare_char2;
+ uint8_t ifi_datalen;
+ uint32_t ifi_mtu;
+ uint32_t ifi_metric;
+ uint32_t ifi_baudrate;
+ uint32_t ifi_ipackets;
+ uint32_t ifi_ierrors;
+ uint32_t ifi_opackets;
+ uint32_t ifi_oerrors;
+ uint32_t ifi_collisions;
+ uint32_t ifi_ibytes;
+ uint32_t ifi_obytes;
+ uint32_t ifi_imcasts;
+ uint32_t ifi_omcasts;
+ uint32_t ifi_iqdrops;
+ uint32_t ifi_noproto;
+ uint32_t ifi_hwassist;
+ int32_t ifi_epoch;
+ struct timeval32 ifi_lastchange;
+};
+
+struct if_msghdr32 {
+ uint16_t ifm_msglen;
+ uint8_t ifm_version;
+ uint8_t ifm_type;
+ int32_t ifm_addrs;
+ int32_t ifm_flags;
+ uint16_t ifm_index;
+ struct if_data32 ifm_data;
+};
+
+struct if_msghdrl32 {
+ uint16_t ifm_msglen;
+ uint8_t ifm_version;
+ uint8_t ifm_type;
+ int32_t ifm_addrs;
+ int32_t ifm_flags;
+ uint16_t ifm_index;
+ uint16_t _ifm_spare1;
+ uint16_t ifm_len;
+ uint16_t ifm_data_off;
+ struct if_data32 ifm_data;
+};
+
+struct ifa_msghdrl32 {
+ uint16_t ifam_msglen;
+ uint8_t ifam_version;
+ uint8_t ifam_type;
+ int32_t ifam_addrs;
+ int32_t ifam_flags;
+ uint16_t ifam_index;
+ uint16_t _ifam_spare1;
+ uint16_t ifam_len;
+ uint16_t ifam_data_off;
+ int32_t ifam_metric;
+ struct if_data32 ifam_data;
+};
+#endif /* COMPAT_FREEBSD32 */
+
MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
/* NB: these are not modified */
@@ -845,6 +915,9 @@ rt_xaddrs(caddr_t cp, caddr_t cplim, str
return (0);
}
+/*
+ * Used by the routing socket.
+ */
static struct mbuf *
rt_msg1(int type, struct rt_addrinfo *rtinfo)
{
@@ -912,6 +985,9 @@ rt_msg1(int type, struct rt_addrinfo *rt
return (m);
}
+/*
+ * Used by the sysctl code and routing socket.
+ */
static int
rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w)
{
@@ -925,11 +1001,31 @@ again:
case RTM_DELADDR:
case RTM_NEWADDR:
- len = sizeof(struct ifa_msghdr);
+ if (w != NULL && w->w_op == NET_RT_IFLISTL) {
+#ifdef COMPAT_FREEBSD32
+ if (w->w_req->flags & SCTL_MASK32)
+ len = sizeof(struct ifa_msghdrl32);
+ else
+#endif
+ len = sizeof(struct ifa_msghdrl);
+ } else
+ len = sizeof(struct ifa_msghdr);
break;
case RTM_IFINFO:
- len = sizeof(struct if_msghdr);
+#ifdef COMPAT_FREEBSD32
+ if (w != NULL && w->w_req->flags & SCTL_MASK32) {
+ if (w->w_op == NET_RT_IFLISTL)
+ len = sizeof(struct if_msghdrl32);
+ else
+ len = sizeof(struct if_msghdr32);
+ break;
+ }
+#endif
+ if (w != NULL && w->w_op == NET_RT_IFLISTL)
+ len = sizeof(struct if_msghdrl);
+ else
+ len = sizeof(struct if_msghdr);
break;
case RTM_NEWMADDR:
@@ -1314,6 +1410,127 @@ sysctl_dumpentry(struct radix_node *rn,
}
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);
+
+ 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;
+
+ return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
+}
+
+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);
+
+ 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;
+
+ return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
+}
+
+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);
+
+ 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;
+
+ return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
+}
+
+static int
+sysctl_iflist_ifam(struct ifaddr *ifa, struct rt_addrinfo *info,
+ struct walkarg *w, int len)
+{
+ struct ifa_msghdr *ifam;
+
+ ifam = (struct ifa_msghdr *)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_metric = ifa->ifa_metric;
+
+ return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
+}
+
+static int
sysctl_iflist(int af, struct walkarg *w)
{
struct ifnet *ifp;
@@ -1332,14 +1549,10 @@ sysctl_iflist(int af, struct walkarg *w)
len = rt_msg2(RTM_IFINFO, &info, NULL, w);
info.rti_info[RTAX_IFP] = NULL;
if (w->w_req && w->w_tmem) {
- struct if_msghdr *ifm;
-
- ifm = (struct if_msghdr *)w->w_tmem;
- ifm->ifm_index = ifp->if_index;
- 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);
+ if (w->w_op == NET_RT_IFLISTL)
+ error = sysctl_iflist_ifml(ifp, &info, w, len);
+ else
+ error = sysctl_iflist_ifm(ifp, &info, w, len);
if (error)
goto done;
}
@@ -1354,14 +1567,12 @@ sysctl_iflist(int af, struct walkarg *w)
info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
len = rt_msg2(RTM_NEWADDR, &info, NULL, w);
if (w->w_req && w->w_tmem) {
- struct ifa_msghdr *ifam;
-
- ifam = (struct ifa_msghdr *)w->w_tmem;
- ifam->ifam_index = ifa->ifa_ifp->if_index;
- 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);
+ if (w->w_op == NET_RT_IFLISTL)
+ error = sysctl_iflist_ifaml(ifa, &info,
+ w, len);
+ else
+ error = sysctl_iflist_ifam(ifa, &info,
+ w, len);
if (error)
goto done;
}
@@ -1473,6 +1684,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
break;
case NET_RT_IFLIST:
+ case NET_RT_IFLISTL:
error = sysctl_iflist(af, &w);
break;
Modified: stable/7/sys/sys/socket.h
==============================================================================
--- stable/7/sys/sys/socket.h Sat May 19 14:32:47 2012 (r235650)
+++ stable/7/sys/sys/socket.h Sat May 19 14:38:14 2012 (r235651)
@@ -416,7 +416,9 @@ struct sockaddr_storage {
#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */
#define NET_RT_IFLIST 3 /* survey interface list */
#define NET_RT_IFMALIST 4 /* return multicast address list */
-#define NET_RT_MAXID 5
+#define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en
+ * versions of msghdr structs. */
+#define NET_RT_MAXID 6
#define CTL_NET_RT_NAMES { \
{ 0, 0 }, \
@@ -424,6 +426,7 @@ struct sockaddr_storage {
{ "flags", CTLTYPE_STRUCT }, \
{ "iflist", CTLTYPE_STRUCT }, \
{ "ifmalist", CTLTYPE_STRUCT }, \
+ { "iflistl", CTLTYPE_STRUCT }, \
}
#endif /* __BSD_VISIBLE */
More information about the svn-src-stable-7
mailing list