diff --git a/sys/net/route.h b/sys/net/route.h index 28f1db01ef8..b01d2555ea1 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -93,6 +93,23 @@ struct rt_metrics { u_long rmx_filler[3]; /* will be used for T/TCP later */ }; +#ifdef _KERNEL +struct rt_metrics32 { + u_int rmx_locks; /* Kernel must leave these values alone */ + u_int rmx_mtu; /* MTU for this path */ + u_int rmx_hopcount; /* max hops expected */ + u_int rmx_expire; /* lifetime for route, e.g. redirect */ + 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 */ + u_int rmx_pksent; /* packets sent using this route */ + u_int rmx_weight; /* route weight */ + u_int rmx_filler[3]; /* will be used for T/TCP later */ +}; +#endif + /* * rmx_rtt and rmx_rttvar are stored as microseconds; * RTTTOPRHZ(rtt) converts to a value suitable for use @@ -263,6 +280,23 @@ struct rt_msghdr { #define RTM_VERSION 5 /* Up the ante and ignore older versions */ +#ifdef _KERNEL +struct rt_msghdr32 { + 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; /* bitmask used in RTM_CHANGE message */ + u_int rtm_inits; /* which metrics we are initializing */ + struct rt_metrics32 rtm_rmx; /* metrics themselves */ +}; +#endif + /* * Message types. * diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 5cdb7a761d0..7bb66c62565 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -1403,21 +1404,46 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle, { struct ifnet *ifp = llt->llt_ifp; /* XXX stack use */ - struct { - struct rt_msghdr rtm; - struct sockaddr_in sin; - struct sockaddr_dl sdl; - } arpc; + union { + struct { + struct rt_msghdr rtm; + struct sockaddr_in sin; + struct sockaddr_dl sdl; + } arpc; +#ifdef COMPAT_FREEBSD32 + struct { + struct rt_msghdr32 rtm; + struct sockaddr_in sin; + struct sockaddr_dl sdl; + } arpc32; +#endif + } au; struct sockaddr_dl *sdl; + struct sockaddr_in *sin; + struct rt_msghdr *rtm; /* Access members through rtm_fmask. */ int error; - bzero(&arpc, sizeof(arpc)); +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) { + rtm = (struct rt_msghdr *)&au.arpc32.rtm; + sdl = &au.arpc32.sdl; + sin = &au.arpc32.sin; + rtm->rtm_msglen = sizeof(au.arpc32); + } else +#endif + { + rtm = (struct rt_msghdr *)&au.arpc.rtm; + sdl = &au.arpc.sdl; + sin = &au.arpc.sin; + rtm->rtm_msglen = sizeof(au.arpc); + } + memset(&au, 0, rtm->rtm_msglen); /* skip deleted entries */ if ((lle->la_flags & LLE_DELETED) == LLE_DELETED) return (0); /* Skip if jailed and not a valid IP of the prison. */ - lltable_fill_sa_entry(lle,(struct sockaddr *)&arpc.sin); - if (prison_if(wr->td->td_ucred, (struct sockaddr *)&arpc.sin) != 0) + lltable_fill_sa_entry(lle,(struct sockaddr *)sin); + if (prison_if(wr->td->td_ucred, (struct sockaddr *)sin) != 0) return (0); /* * produce a msg made of: @@ -1425,17 +1451,15 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle, * struct sockaddr_in; (IPv4) * struct sockaddr_dl; */ - arpc.rtm.rtm_msglen = sizeof(arpc); - arpc.rtm.rtm_version = RTM_VERSION; - arpc.rtm.rtm_type = RTM_GET; - arpc.rtm.rtm_flags = RTF_UP; - arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_flags = RTF_UP; + rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; /* publish */ if (lle->la_flags & LLE_PUB) - arpc.rtm.rtm_flags |= RTF_ANNOUNCE; + rtm->rtm_flags |= RTF_ANNOUNCE; - sdl = &arpc.sdl; sdl->sdl_family = AF_LINK; sdl->sdl_len = sizeof(*sdl); sdl->sdl_index = ifp->if_index; @@ -1448,15 +1472,21 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle, bzero(LLADDR(sdl), ifp->if_addrlen); } - arpc.rtm.rtm_rmx.rmx_expire = - lle->la_flags & LLE_STATIC ? 0 : lle->la_expire; - arpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA); +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) + au.arpc32.rtm.rtm_rmx.rmx_expire = + lle->la_flags & LLE_STATIC ? 0 : lle->la_expire; + else +#endif + au.arpc.rtm.rtm_rmx.rmx_expire = + lle->la_flags & LLE_STATIC ? 0 : lle->la_expire; + rtm->rtm_flags |= (RTF_HOST | RTF_LLDATA); if (lle->la_flags & LLE_STATIC) - arpc.rtm.rtm_flags |= RTF_STATIC; + rtm->rtm_flags |= RTF_STATIC; if (lle->la_flags & LLE_IFADDR) - arpc.rtm.rtm_flags |= RTF_PINNED; - arpc.rtm.rtm_index = ifp->if_index; - error = SYSCTL_OUT(wr, &arpc, sizeof(arpc)); + rtm->rtm_flags |= RTF_PINNED; + rtm->rtm_index = ifp->if_index; + error = SYSCTL_OUT(wr, &au, rtm->rtm_msglen); return (error); } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 39c3904eaf9..32736b10434 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2335,27 +2336,52 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, { struct ifnet *ifp = llt->llt_ifp; /* XXX stack use */ - struct { - struct rt_msghdr rtm; - struct sockaddr_in6 sin6; - /* - * ndp.c assumes that sdl is word aligned - */ + union { + struct { + struct rt_msghdr rtm; + struct sockaddr_in6 sin6; + /* + * ndp.c assumes that sdl is word aligned + */ #ifdef __LP64__ - uint32_t pad; + uint32_t pad; #endif - struct sockaddr_dl sdl; - } ndpc; + struct sockaddr_dl sdl; + } ndpc; +#ifdef COMPAT_FREEBSD32 + struct { + struct rt_msghdr32 rtm; + struct sockaddr_in6 sin6; + struct sockaddr_dl sdl; + } ndpc32; +#endif + } nu; struct sockaddr_dl *sdl; + struct sockaddr_in6 *sin6; + struct rt_msghdr *rtm; /* Access members through rtm_fmask. */ int error; - bzero(&ndpc, sizeof(ndpc)); +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) { + rtm = (struct rt_msghdr *)&nu.ndpc32.rtm; + sdl = &nu.ndpc32.sdl; + sin6 = &nu.ndpc32.sin6; + rtm->rtm_msglen = sizeof(nu.ndpc32); + } else +#endif + { + rtm = &nu.ndpc.rtm; + sdl = &nu.ndpc.sdl; + sin6 = &nu.ndpc.sin6; + rtm->rtm_msglen = sizeof(nu.ndpc); + } + memset(&nu, 0, rtm->rtm_msglen); /* skip deleted entries */ if ((lle->la_flags & LLE_DELETED) == LLE_DELETED) return (0); /* Skip if jailed and not a valid IP of the prison. */ - lltable_fill_sa_entry(lle, (struct sockaddr *)&ndpc.sin6); - if (prison_if(wr->td->td_ucred, (struct sockaddr *)&ndpc.sin6) != 0) + lltable_fill_sa_entry(lle, (struct sockaddr *)sin6); + if (prison_if(wr->td->td_ucred, (struct sockaddr *)sin6) != 0) return (0); /* * produce a msg made of: @@ -2363,19 +2389,17 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, * struct sockaddr_in6 (IPv6) * struct sockaddr_dl; */ - ndpc.rtm.rtm_msglen = sizeof(ndpc); - ndpc.rtm.rtm_version = RTM_VERSION; - ndpc.rtm.rtm_type = RTM_GET; - ndpc.rtm.rtm_flags = RTF_UP; - ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_flags = RTF_UP; + rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; if (V_deembed_scopeid) - sa6_recoverscope(&ndpc.sin6); + sa6_recoverscope(sin6); /* publish */ if (lle->la_flags & LLE_PUB) - ndpc.rtm.rtm_flags |= RTF_ANNOUNCE; + rtm->rtm_flags |= RTF_ANNOUNCE; - sdl = &ndpc.sdl; sdl->sdl_family = AF_LINK; sdl->sdl_len = sizeof(*sdl); sdl->sdl_index = ifp->if_index; @@ -2387,21 +2411,33 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, sdl->sdl_alen = 0; bzero(LLADDR(sdl), ifp->if_addrlen); } - if (lle->la_expire != 0) - ndpc.rtm.rtm_rmx.rmx_expire = lle->la_expire + - lle->lle_remtime / hz + time_second - time_uptime; - ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA); + rtm->rtm_flags |= (RTF_HOST | RTF_LLDATA); if (lle->la_flags & LLE_STATIC) - ndpc.rtm.rtm_flags |= RTF_STATIC; + rtm->rtm_flags |= RTF_STATIC; if (lle->la_flags & LLE_IFADDR) - ndpc.rtm.rtm_flags |= RTF_PINNED; + rtm->rtm_flags |= RTF_PINNED; if (lle->ln_router != 0) - ndpc.rtm.rtm_flags |= RTF_GATEWAY; - ndpc.rtm.rtm_rmx.rmx_pksent = lle->la_asked; - /* Store state in rmx_weight value */ - ndpc.rtm.rtm_rmx.rmx_state = lle->ln_state; - ndpc.rtm.rtm_index = ifp->if_index; - error = SYSCTL_OUT(wr, &ndpc, sizeof(ndpc)); + rtm->rtm_flags |= RTF_GATEWAY; +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) { + if (lle->la_expire != 0) + nu.ndpc32.rtm.rtm_rmx.rmx_expire = lle->la_expire + + lle->lle_remtime / hz + time_second - time_uptime; + nu.ndpc32.rtm.rtm_rmx.rmx_pksent = lle->la_asked; + /* Store state in rmx_weight value */ + nu.ndpc32.rtm.rtm_rmx.rmx_state = lle->ln_state; + } else +#endif + { + if (lle->la_expire != 0) + nu.ndpc.rtm.rtm_rmx.rmx_expire = lle->la_expire + + lle->lle_remtime / hz + time_second - time_uptime; + nu.ndpc.rtm.rtm_rmx.rmx_pksent = lle->la_asked; + /* Store state in rmx_weight value */ + nu.ndpc.rtm.rtm_rmx.rmx_state = lle->ln_state; + } + rtm->rtm_index = ifp->if_index; + error = SYSCTL_OUT(wr, &nu, rtm->rtm_msglen); return (error); }