diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2007-09-03 15:24:50 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2007-09-03 15:24:50 +0000 |
commit | 66e75d800387effae4d92db63dbfc58d0dcce5b3 (patch) | |
tree | d81fcade71677827092118d136feb9e1da27fd6d | |
parent | 8a2f9322df090c3700e0005211d34b8426138f95 (diff) |
Bump RTM_VERSION to 4 and start a new aera of routing in OpenBSD :)
Changes include 64bit counters instead of u_long, routing table id in the header
of most messages, reserved routing priority field, added a hdrlen field to skip
over the header so that binary compatibility becomes easier.
A minimal backward support for old binaries is included to ease upgrades but
don't expect anything more than ifconfig, route and dhclient to correctly work.
OK henning@ mglocker@
-rw-r--r-- | sys/net/if.h | 108 | ||||
-rw-r--r-- | sys/net/route.h | 84 | ||||
-rw-r--r-- | sys/net/rtsock.c | 224 |
3 files changed, 334 insertions, 82 deletions
diff --git a/sys/net/if.h b/sys/net/if.h index 4b6011ca8ac..552e7b07401 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.91 2007/06/25 16:37:58 henning Exp $ */ +/* $OpenBSD: if.h,v 1.92 2007/09/03 15:24:49 claudio Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -110,25 +110,26 @@ struct if_clonereq { */ struct if_data { /* generic interface information */ - u_char ifi_type; /* ethernet, tokenring, etc. */ - u_char ifi_addrlen; /* media address length */ - u_char ifi_hdrlen; /* media header length */ - u_char ifi_link_state; /* current link state */ - u_long ifi_mtu; /* maximum transmission unit */ - u_long ifi_metric; /* routing metric (external only) */ - u_long ifi_baudrate; /* linespeed */ + u_char ifi_type; /* ethernet, tokenring, etc. */ + u_char ifi_addrlen; /* media address length */ + u_char ifi_hdrlen; /* media header length */ + u_char ifi_link_state; /* current link state */ + u_int32_t ifi_mtu; /* maximum transmission unit */ + u_int32_t ifi_metric; /* routing metric (external only) */ + u_int32_t ifi_pad; + u_int64_t ifi_baudrate; /* linespeed */ /* volatile statistics */ - u_long ifi_ipackets; /* packets received on interface */ - u_long ifi_ierrors; /* input errors on interface */ - u_long ifi_opackets; /* packets sent on interface */ - u_long ifi_oerrors; /* output errors on interface */ - u_long ifi_collisions; /* collisions on csma interfaces */ - u_long ifi_ibytes; /* total number of octets received */ - u_long ifi_obytes; /* total number of octets sent */ - u_long ifi_imcasts; /* packets received via multicast */ - u_long ifi_omcasts; /* packets sent via multicast */ - u_long ifi_iqdrops; /* dropped on input, this interface */ - u_long ifi_noproto; /* destined for unsupported protocol */ + u_int64_t ifi_ipackets; /* packets received on interface */ + u_int64_t ifi_ierrors; /* input errors on interface */ + u_int64_t ifi_opackets; /* packets sent on interface */ + u_int64_t ifi_oerrors; /* output errors on interface */ + u_int64_t ifi_collisions; /* collisions on csma interfaces */ + u_int64_t ifi_ibytes; /* total number of octets received */ + u_int64_t ifi_obytes; /* total number of octets sent */ + u_int64_t ifi_imcasts; /* packets received via multicast */ + u_int64_t ifi_omcasts; /* packets sent via multicast */ + u_int64_t ifi_iqdrops; /* dropped on input, this interface */ + u_int64_t ifi_noproto; /* destined for unsupported protocol */ struct timeval ifi_lastchange; /* last operational state change */ }; @@ -266,9 +267,9 @@ struct ifnet { /* and the entries */ /* * Some convenience macros used for setting ifi_baudrate. */ -#define IF_Kbps(x) ((x) * 1000) /* kilobits/sec. */ -#define IF_Mbps(x) (IF_Kbps((x) * 1000)) /* megabits/sec. */ -#define IF_Gbps(x) (IF_Mbps((x) * 1000)) /* gigabits/sec. */ +#define IF_Kbps(x) ((x) * 1000ULL) /* kilobits/sec. */ +#define IF_Mbps(x) (IF_Kbps((x) * 1000ULL)) /* megabits/sec. */ +#define IF_Gbps(x) (IF_Mbps((x) * 1000ULL)) /* gigabits/sec. */ /* Capabilities that interfaces can advertise. */ #define IFCAP_CSUM_IPv4 0x00000001 /* can do IPv4 header csum */ @@ -394,9 +395,13 @@ struct if_msghdr { u_short ifm_msglen; /* to skip over non-understood messages */ u_char ifm_version; /* future binary compatibility */ u_char ifm_type; /* message type */ + u_short ifm_hdrlen; /* sizeof(if_msghdr) to skip over the header */ + u_short ifm_index; /* index for associated ifp */ + u_short ifm_tableid; /* routing table id */ + u_short ifm_pad; int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ - u_short ifm_index; /* index for associated ifp */ + int ifm_pad2; struct if_data ifm_data;/* statistics and other data about if */ }; @@ -408,9 +413,12 @@ struct ifa_msghdr { u_short ifam_msglen; /* to skip over non-understood messages */ u_char ifam_version; /* future binary compatibility */ u_char ifam_type; /* message type */ + u_short ifam_hdrlen; /* sizeof(ifa_msghdr) to skip over the header */ + u_short ifam_index; /* index for associated ifp */ + u_short ifam_tableid; /* routing table id */ + u_short ifam_pad; int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ - u_short ifam_index; /* index for associated ifp */ int ifam_metric; /* value of ifa_metric */ }; @@ -422,15 +430,65 @@ struct if_announcemsghdr { u_short ifan_msglen; /* to skip over non-understood messages */ u_char ifan_version; /* future binary compatibility */ u_char ifan_type; /* message type */ + u_short ifan_hdrlen; /* sizeof(ifa_msghdr) to skip over the header */ u_short ifan_index; /* index for associated ifp */ - char ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */ u_short ifan_what; /* what type of announcement */ + char ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */ }; #define IFAN_ARRIVAL 0 /* interface arrival */ #define IFAN_DEPARTURE 1 /* interface departure */ /* + * Comaptibility structures for version 3 messages. + * Keep them till after OpenBSD 4.4 + */ +struct if_odata { + /* generic interface information */ + u_char ifi_type; /* ethernet, tokenring, etc. */ + u_char ifi_addrlen; /* media address length */ + u_char ifi_hdrlen; /* media header length */ + u_char ifi_link_state; /* current link state */ + u_long ifi_mtu; /* maximum transmission unit */ + u_long ifi_metric; /* routing metric (external only) */ + u_long ifi_baudrate; /* linespeed */ + /* volatile statistics */ + u_long ifi_ipackets; /* packets received on interface */ + u_long ifi_ierrors; /* input errors on interface */ + u_long ifi_opackets; /* packets sent on interface */ + u_long ifi_oerrors; /* output errors on interface */ + u_long ifi_collisions; /* collisions on csma interfaces */ + u_long ifi_ibytes; /* total number of octets received */ + u_long ifi_obytes; /* total number of octets sent */ + u_long ifi_imcasts; /* packets received via multicast */ + u_long ifi_omcasts; /* packets sent via multicast */ + u_long ifi_iqdrops; /* dropped on input, this interface */ + u_long ifi_noproto; /* destined for unsupported protocol */ + struct timeval ifi_lastchange; /* last operational state change */ +}; + +struct if_omsghdr { + 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 */ + struct if_odata ifm_data;/* statistics and other data about if */ +}; + +struct ifa_omsghdr { + 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 */ + int ifam_metric; /* value of ifa_metric */ +}; + + +/* * interface groups */ diff --git a/sys/net/route.h b/sys/net/route.h index e6e370c337f..ab82113c816 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.46 2006/06/18 11:47:45 pascoe Exp $ */ +/* $OpenBSD: route.h,v 1.47 2007/09/03 15:24:49 claudio Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -59,30 +59,30 @@ struct route { * retransmission behavior and are included in the routing structure. */ struct rt_kmetrics { - u_long rmx_locks; /* Kernel must leave these values alone */ - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_expire; /* lifetime for route, e.g. redirect */ - u_long rmx_pksent; /* packets sent using this route */ + u_int64_t rmx_pksent; /* packets sent using this route */ + u_int rmx_locks; /* Kernel must leave these values */ + u_int rmx_mtu; /* MTU for this path */ + u_int rmx_expire; /* lifetime for route, e.g. redirect */ + u_int rmx_pad; }; /* * Huge version for userland compatibility. */ struct rt_metrics { - u_long rmx_locks; /* Kernel must leave these values alone */ - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_hopcount; /* max hops expected */ - u_long rmx_expire; /* lifetime for route, e.g. redirect */ - u_long rmx_recvpipe; /* inbound delay-bandwidth product */ - u_long rmx_sendpipe; /* outbound delay-bandwidth product */ - u_long rmx_ssthresh; /* outbound gateway buffer limit (deprecated) */ - u_long rmx_rtt; /* estimated round trip time (deprecated) */ - u_long rmx_rttvar; /* estimated rtt variance (deprecated) */ - u_long rmx_pksent; /* packets sent using this route */ + u_int64_t rmx_pksent; /* packets sent using this route */ + u_int rmx_locks; /* Kernel must leave these values */ + u_int rmx_mtu; /* MTU for this path */ + u_int rmx_expire; /* lifetime for route, e.g. redirect */ + u_int rmx_refcnt; /* # references hold */ + /* some apps may still need these no longer used metrics */ + u_int rmx_hopcount; /* max hops expected */ + u_int rmx_recvpipe; /* inbound delay-bandwidth product */ + u_int rmx_sendpipe; /* outbound delay-bandwidth product */ + u_int rmx_ssthresh; /* outbound gateway buffer limit */ + u_int rmx_rtt; /* estimated round trip time */ + u_int rmx_rttvar; /* estimated rtt variance */ }; -/* XXX overloading some values that are no longer used. */ -#define rmx_refcnt rmx_rttvar /* # held references only used by sysctl */ -#define rmx_rt_tableid rmx_rtt /* routing table ID */ /* * rmx_rtt and rmx_rttvar are stored as microseconds; @@ -172,21 +172,57 @@ struct rt_msghdr { u_short rtm_msglen; /* to skip over non-understood messages */ u_char rtm_version; /* future binary compatibility */ u_char rtm_type; /* message type */ + u_short rtm_hdrlen; /* sizeof(rt_msghdr) to skip over the header */ u_short rtm_index; /* index for associated ifp */ - int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + u_short rtm_tableid; /* routing table id */ + u_char rtm_prio; /* routing priority */ + u_char rtm_pad; int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_fmask; /* bitmask used in RTM_CHANGE message */ pid_t rtm_pid; /* identify sender */ int rtm_seq; /* for sender to identify action */ int rtm_errno; /* why failed */ - int rtm_use; /* deprecated use rtm_rmx->rmx_pksent */ -#define rtm_fmask rtm_use /* bitmask used in RTM_CHANGE message */ - u_long rtm_inits; /* which metrics we are initializing */ + u_int rtm_inits; /* which metrics we are initializing */ struct rt_metrics rtm_rmx; /* metrics themselves */ }; /* overload no longer used field */ -#define rtm_tableid rtm_rmx.rmx_rt_tableid +#define rtm_use rtm_rmx.rmx_pksent + +/* + * Comaptibility structures for version 3 messages. + * Keep them till after OpenBSD 4.4 + */ +struct rt_ometrics { + u_long rmx_locks; /* Kernel must leave these values alone */ + u_long rmx_mtu; /* MTU for this path */ + u_long rmx_hopcount; /* max hops expected (deprecated) */ + u_long rmx_expire; /* lifetime for route, e.g. redirect */ + u_long rmx_recvpipe; /* inbound delay-bandwidth product */ + u_long rmx_sendpipe; /* outbound delay-bandwidth product */ + u_long rmx_ssthresh; /* outbound gateway buffer limit (deprecated) */ + u_long rmx_rtt; /* overloaded with rmx_rt_tableid */ + u_long rmx_rttvar; /* estimated rtt variance (deprecated) */ + u_long rmx_pksent; /* packets sent using this route */ +}; + +struct rt_omsghdr { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + pid_t rtm_pid; /* identify sender */ + int rtm_seq; /* for sender to identify action */ + int rtm_errno; /* why failed */ + int rtm_fmask; /* was once rtm_use */ + u_long rtm_inits; /* which metrics we are initializing */ + struct rt_ometrics rtm_rmx; /* metrics themselves */ +}; -#define RTM_VERSION 3 /* Up the ante and ignore older versions */ +#define RTM_OVERSION 3 /* provide some minimal backward compat */ +#define RTM_VERSION 4 /* Up the ante and ignore older versions */ #define RTM_ADD 0x1 /* Add Route */ #define RTM_DELETE 0x2 /* Delete Route */ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 563d40efe36..9ccb8befa4a 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.63 2007/02/14 00:53:48 jsg Exp $ */ +/* $OpenBSD: rtsock.c,v 1.64 2007/09/03 15:24:49 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -88,10 +88,13 @@ struct walkarg { caddr_t w_where, w_tmem; }; -static struct mbuf - *rt_msg1(int, struct rt_addrinfo *); -static int rt_msg2(int, struct rt_addrinfo *, caddr_t, struct walkarg *); -static void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); +struct mbuf *rt_msg1(int, struct rt_addrinfo *); +int rt_msg2(int, int, struct rt_addrinfo *, caddr_t, + struct walkarg *); +void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); +#ifndef SMALL_KERNEL +struct rt_msghdr *rtmsg_3to4(struct mbuf *, int *); +#endif /* Sleazy use of local variables throughout file, warning!!!! */ #define dst info.rti_info[RTAX_DST] @@ -187,25 +190,50 @@ route_output(struct mbuf *m, ...) if ((m->m_flags & M_PKTHDR) == 0) panic("route_output"); len = m->m_pkthdr.len; - if (len < sizeof(*rtm) || + if (len < offsetof(struct rt_msghdr, rtm_type) + 1 || len != mtod(m, struct rt_msghdr *)->rtm_msglen) { dst = 0; error = EINVAL; goto flush; } - R_Malloc(rtm, struct rt_msghdr *, len); - if (rtm == 0) { - dst = 0; - error = ENOBUFS; - goto flush; - } - m_copydata(m, 0, len, (caddr_t)rtm); - if (rtm->rtm_version != RTM_VERSION) { + switch (mtod(m, struct rt_msghdr *)->rtm_version) { + case RTM_VERSION: + if (len < sizeof(struct rt_msghdr)) { + dst = 0; + error = EINVAL; + goto flush; + } + R_Malloc(rtm, struct rt_msghdr *, len); + if (rtm == 0) { + dst = 0; + error = ENOBUFS; + goto flush; + } + m_copydata(m, 0, len, (caddr_t)rtm); + break; +#ifndef SMALL_KERNEL + case RTM_OVERSION: + if (len < sizeof(struct rt_omsghdr)) { + dst = 0; + error = EINVAL; + goto flush; + } + rtm = rtmsg_3to4(m, &len); + if (rtm == 0) { + dst = 0; + error = ENOBUFS; + goto flush; + } + break; +#endif + default: dst = 0; error = EPROTONOSUPPORT; goto flush; } rtm->rtm_pid = curproc->p_pid; + if (rtm->rtm_hdrlen == 0) /* old client */ + rtm->rtm_hdrlen = sizeof(struct rt_msghdr); tableid = rtm->rtm_tableid; if (!rtable_exists(tableid)) { @@ -222,7 +250,7 @@ route_output(struct mbuf *m, ...) bzero(&info, sizeof(info)); info.rti_addrs = rtm->rtm_addrs; - rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info); + rt_xaddrs(rtm->rtm_hdrlen + (caddr_t)rtm, len + (caddr_t)rtm, &info); info.rti_flags = rtm->rtm_flags; if (dst == 0 || dst->sa_family >= AF_MAX || (gate != 0 && gate->sa_family >= AF_MAX)) { @@ -354,7 +382,8 @@ report: brdaddr = 0; rtm->rtm_index = ifp->if_index; } - len = rt_msg2(rtm->rtm_type, &info, NULL, NULL); + len = rt_msg2(rtm->rtm_type, RTM_VERSION, &info, NULL, + NULL); if (len > rtm->rtm_msglen) { struct rt_msghdr *new_rtm; R_Malloc(new_rtm, struct rt_msghdr *, len); @@ -365,7 +394,8 @@ report: Bcopy(rtm, new_rtm, rtm->rtm_msglen); Free(rtm); rtm = new_rtm; } - rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL); + rt_msg2(rtm->rtm_type, RTM_VERSION, &info, (caddr_t)rtm, + NULL); rtm->rtm_flags = rt->rt_flags; rtm->rtm_use = 0; rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); @@ -507,7 +537,7 @@ rt_getmetrics(struct rt_kmetrics *in, struct rt_metrics *out) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) -static void +void rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) { struct sockaddr *sa; @@ -522,14 +552,14 @@ rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) } } -static struct mbuf * +struct mbuf * rt_msg1(int type, struct rt_addrinfo *rtinfo) { struct rt_msghdr *rtm; struct mbuf *m; int i; struct sockaddr *sa; - int len, dlen; + int len, dlen, hlen; switch (type) { case RTM_DELADDR: @@ -558,7 +588,7 @@ rt_msg1(int type, struct rt_addrinfo *rtinfo) } if (m == 0) return (m); - m->m_pkthdr.len = m->m_len = len; + m->m_pkthdr.len = m->m_len = hlen = len; m->m_pkthdr.rcvif = NULL; rtm = mtod(m, struct rt_msghdr *); bzero(rtm, len); @@ -575,16 +605,18 @@ rt_msg1(int type, struct rt_addrinfo *rtinfo) return (NULL); } rtm->rtm_msglen = len; + rtm->rtm_hdrlen = hlen; rtm->rtm_version = RTM_VERSION; rtm->rtm_type = type; return (m); } -static int -rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w) +int +rt_msg2(int type, int vers, struct rt_addrinfo *rtinfo, caddr_t cp, + struct walkarg *w) { int i; - int len, dlen, second_time = 0; + int len, dlen, hlen, second_time = 0; caddr_t cp0; rtinfo->rti_addrs = 0; @@ -592,15 +624,31 @@ again: switch (type) { case RTM_DELADDR: case RTM_NEWADDR: - len = sizeof(struct ifa_msghdr); +#ifndef SMALL_KERNEL + if (vers == RTM_OVERSION) + len = sizeof(struct ifa_omsghdr); + else +#endif + len = sizeof(struct ifa_msghdr); break; case RTM_IFINFO: - len = sizeof(struct if_msghdr); +#ifndef SMALL_KERNEL + if (vers == RTM_OVERSION) + len = sizeof(struct if_omsghdr); + else +#endif + len = sizeof(struct if_msghdr); break; default: - len = sizeof(struct rt_msghdr); +#ifndef SMALL_KERNEL + if (vers == RTM_OVERSION) + len = sizeof(struct rt_omsghdr); + else +#endif + len = sizeof(struct rt_msghdr); break; } + hlen = len; if ((cp0 = cp) != NULL) cp += len; for (i = 0; i < RTAX_MAX; i++) { @@ -636,13 +684,23 @@ again: rw->w_where = 0; } } - if (cp) { + if (cp && vers != RTM_OVERSION) { struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; rtm->rtm_version = RTM_VERSION; rtm->rtm_type = type; rtm->rtm_msglen = len; + rtm->rtm_hdrlen = hlen; + } +#ifndef SMALL_KERNEL + if (cp && vers == RTM_OVERSION) { + struct rt_omsghdr *rtm = (struct rt_omsghdr *)cp0; + + rtm->rtm_version = RTM_OVERSION; + rtm->rtm_type = type; + rtm->rtm_msglen = len; } +#endif return (len); } @@ -836,14 +894,31 @@ sysctl_dumpentry(struct radix_node *rn, void *v) } } - size = rt_msg2(RTM_GET, &info, NULL, w); + size = rt_msg2(RTM_GET, RTM_VERSION, &info, NULL, w); if (w->w_where && w->w_tmem && w->w_needed <= 0) { struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; rtm->rtm_flags = rt->rt_flags; rtm->rtm_use = 0; rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); - rtm->rtm_rmx.rmx_refcnt = (u_long)rt->rt_refcnt; + rtm->rtm_rmx.rmx_refcnt = rt->rt_refcnt; + rtm->rtm_index = rt->rt_ifp->if_index; + rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; + rtm->rtm_addrs = info.rti_addrs; + if ((error = copyout(rtm, w->w_where, size)) != 0) + w->w_where = NULL; + else + w->w_where += size; + } +#ifndef SMALL_KERNEL + size = rt_msg2(RTM_GET, RTM_OVERSION, &info, NULL, w); + if (w->w_where && w->w_tmem && w->w_needed <= 0) { + struct rt_omsghdr *rtm = (struct rt_omsghdr *)w->w_tmem; + + rtm->rtm_flags = rt->rt_flags; + rtm->rtm_use = 0; + rtm->rtm_rmx.rmx_locks = rt->rt_rmx.rmx_locks; + rtm->rtm_rmx.rmx_mtu = rt->rt_rmx.rmx_mtu; rtm->rtm_index = rt->rt_ifp->if_index; rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; rtm->rtm_addrs = info.rti_addrs; @@ -852,6 +927,7 @@ sysctl_dumpentry(struct radix_node *rn, void *v) else w->w_where += size; } +#endif return (error); } @@ -871,8 +947,7 @@ sysctl_iflist(int af, struct walkarg *w) if (!ifa) continue; ifpaddr = ifa->ifa_addr; - len = rt_msg2(RTM_IFINFO, &info, 0, w); - ifpaddr = 0; + len = rt_msg2(RTM_IFINFO, RTM_VERSION, &info, 0, w); if (w->w_where && w->w_tmem && w->w_needed <= 0) { struct if_msghdr *ifm; @@ -886,6 +961,36 @@ sysctl_iflist(int af, struct walkarg *w) return (error); w->w_where += len; } +#ifndef SMALL_KERNEL + len = rt_msg2(RTM_IFINFO, RTM_OVERSION, &info, 0, w); + if (w->w_where && w->w_tmem && w->w_needed <= 0) { + struct if_omsghdr *ifm; + + ifm = (struct if_omsghdr *)w->w_tmem; + ifm->ifm_index = ifp->if_index; + ifm->ifm_flags = ifp->if_flags; + /* just init the most important types of if_data */ + ifm->ifm_data.ifi_type = ifp->if_data.ifi_type; + ifm->ifm_data.ifi_addrlen = ifp->if_data.ifi_addrlen; + ifm->ifm_data.ifi_hdrlen = ifp->if_data.ifi_hdrlen; + ifm->ifm_data.ifi_link_state = + ifp->if_data.ifi_link_state; + ifm->ifm_data.ifi_mtu = ifp->if_data.ifi_mtu; + ifm->ifm_data.ifi_metric = ifp->if_data.ifi_metric; + if (ifp->if_data.ifi_baudrate > ULONG_MAX) + ifm->ifm_data.ifi_baudrate = ULONG_MAX; + else + ifm->ifm_data.ifi_baudrate = + ifp->if_data.ifi_baudrate; + + ifm->ifm_addrs = info.rti_addrs; + error = copyout(ifm, w->w_where, len); + if (error) + return (error); + w->w_where += len; + } +#endif + ifpaddr = 0; while ((ifa = TAILQ_NEXT(ifa, ifa_list)) != TAILQ_END(&ifp->if_addrlist)) { if (af && af != ifa->ifa_addr->sa_family) @@ -893,7 +998,7 @@ sysctl_iflist(int af, struct walkarg *w) ifaaddr = ifa->ifa_addr; netmask = ifa->ifa_netmask; brdaddr = ifa->ifa_dstaddr; - len = rt_msg2(RTM_NEWADDR, &info, 0, w); + len = rt_msg2(RTM_NEWADDR, RTM_VERSION, &info, 0, w); if (w->w_where && w->w_tmem && w->w_needed <= 0) { struct ifa_msghdr *ifam; @@ -907,6 +1012,22 @@ sysctl_iflist(int af, struct walkarg *w) return (error); w->w_where += len; } +#ifndef SMALL_KERNEL + len = rt_msg2(RTM_NEWADDR, RTM_OVERSION, &info, 0, w); + if (w->w_where && w->w_tmem && w->w_needed <= 0) { + struct ifa_omsghdr *ifam; + + ifam = (struct ifa_omsghdr *)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 = copyout(w->w_tmem, w->w_where, len); + if (error) + return (error); + w->w_where += len; + } +#endif } ifaaddr = netmask = brdaddr = 0; } @@ -978,6 +1099,43 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, return (error); } +#ifndef SMALL_KERNEL +struct rt_msghdr * +rtmsg_3to4(struct mbuf *m, int *len) +{ + struct rt_msghdr *rtm; + struct rt_omsghdr *ortm; + int slen; + + slen = *len - sizeof(struct rt_omsghdr); + *len = sizeof(struct rt_msghdr) + slen; + R_Malloc(rtm, struct rt_msghdr *, *len); + if (rtm == 0) + return (NULL); + bzero(rtm, sizeof(struct rt_msghdr)); + ortm = mtod(m, struct rt_omsghdr *); + rtm->rtm_msglen = sizeof(struct rt_msghdr) + slen; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = ortm->rtm_type; + rtm->rtm_hdrlen = sizeof(struct rt_msghdr); + rtm->rtm_index = ortm->rtm_index; + rtm->rtm_tableid = 0; /* XXX we only care about the main table */ + rtm->rtm_flags = ortm->rtm_flags; + rtm->rtm_addrs = ortm->rtm_addrs; + rtm->rtm_seq = ortm->rtm_seq; + rtm->rtm_fmask = ortm->rtm_fmask; + rtm->rtm_inits = ortm->rtm_inits; + /* copy just the interesting stuff ignore the rest */ + rtm->rtm_rmx.rmx_locks = ortm->rtm_rmx.rmx_locks; + rtm->rtm_rmx.rmx_mtu = ortm->rtm_rmx.rmx_mtu; + + m_copydata(m, sizeof(struct rt_omsghdr), slen, + ((caddr_t)rtm + sizeof(struct rt_msghdr))); + + return (rtm); +} +#endif + /* * Definitions of protocols supported in the ROUTE domain. */ |