summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2007-09-03 15:24:50 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2007-09-03 15:24:50 +0000
commit66e75d800387effae4d92db63dbfc58d0dcce5b3 (patch)
treed81fcade71677827092118d136feb9e1da27fd6d
parent8a2f9322df090c3700e0005211d34b8426138f95 (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.h108
-rw-r--r--sys/net/route.h84
-rw-r--r--sys/net/rtsock.c224
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.
*/