Guest User

FreeBSD 9-STABLE support routing i386 vnet jails on amd64

a guest
Apr 16th, 2013
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.10 KB | None | 0 0
  1. --- sys/net/rtsock.c.orig 2013-04-15 03:37:01.713760711 +0000
  2. +++ sys/net/rtsock.c 2013-04-16 21:08:21.398951884 +0000
  3. @@ -75,6 +75,7 @@
  4.  
  5. #ifdef COMPAT_FREEBSD32
  6. #include <sys/mount.h>
  7. +#include <sys/sysent.h>
  8. #include <compat/freebsd32/freebsd32.h>
  9.  
  10. struct if_data32 {
  11. @@ -141,6 +142,43 @@
  12. int32_t ifam_metric;
  13. struct if_data32 ifam_data;
  14. };
  15. +
  16. +struct rt_metrics32 {
  17. + uint32_t rmx_locks;
  18. + uint32_t rmx_mtu;
  19. + uint32_t rmx_hopcount;
  20. + uint32_t rmx_expire;
  21. + uint32_t rmx_recvpipe;
  22. + uint32_t rmx_sendpipe;
  23. + uint32_t rmx_ssthresh;
  24. + uint32_t rmx_rtt;
  25. + uint32_t rmx_rttvar;
  26. + uint32_t rmx_pksent;
  27. + uint32_t rmx_weight;
  28. + uint32_t rmx_filler[3];
  29. +};
  30. +
  31. +struct rt_msghdr32 {
  32. + uint16_t rtm_msglen;
  33. + uint8_t rtm_version;
  34. + uint8_t rtm_type;
  35. + uint16_t rtm_index;
  36. + uint16_t rtm_hole1;
  37. + uint32_t rtm_flags;
  38. + uint32_t rtm_addrs;
  39. + uint32_t rtm_pid;
  40. + uint32_t rtm_seq;
  41. + uint32_t rtm_errno;
  42. + uint32_t rtm_fmask;
  43. + uint32_t rtm_inits;
  44. + struct rt_metrics32 rtm_rmx;
  45. +};
  46. +
  47. +#define SA_SIZE32(sa) \
  48. + ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \
  49. + sizeof(int32_t) : \
  50. + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int32_t) - 1)))
  51. +
  52. #endif /* COMPAT_FREEBSD32 */
  53.  
  54. MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
  55. @@ -560,6 +598,138 @@
  56. return (0);
  57. }
  58.  
  59. +#ifdef COMPAT_FREEBSD32
  60. +static void
  61. +freebsd32_rt_metrics_in(struct rt_metrics32 *src, struct rt_metrics *dst)
  62. +{
  63. +
  64. + bzero(dst, sizeof(*dst));
  65. + CP(*src, *dst, rmx_mtu);
  66. + CP(*src, *dst, rmx_expire);
  67. + CP(*src, *dst, rmx_pksent);
  68. + CP(*src, *dst, rmx_weight);
  69. +}
  70. +
  71. +static void
  72. +freebsd32_rt_metrics_out(struct rt_metrics *src, struct rt_metrics32 *dst)
  73. +{
  74. +
  75. + bzero(dst, sizeof(*dst));
  76. + CP(*src, *dst, rmx_mtu);
  77. + CP(*src, *dst, rmx_expire);
  78. + CP(*src, *dst, rmx_pksent);
  79. + CP(*src, *dst, rmx_weight);
  80. +}
  81. +
  82. +static void
  83. +freebsd32_rt_msghdr_in(struct rt_msghdr32 *src, struct rt_msghdr *dst)
  84. +{
  85. +
  86. + bzero(dst, sizeof(*dst));
  87. + /* CP(*src, *dst, rtm_msglen); */ /* updated separately */
  88. + CP(*src, *dst, rtm_version);
  89. + CP(*src, *dst, rtm_type);
  90. + CP(*src, *dst, rtm_index);
  91. + CP(*src, *dst, rtm_flags);
  92. + CP(*src, *dst, rtm_addrs);
  93. + CP(*src, *dst, rtm_pid);
  94. + CP(*src, *dst, rtm_seq);
  95. + CP(*src, *dst, rtm_errno);
  96. + CP(*src, *dst, rtm_fmask);
  97. + CP(*src, *dst, rtm_inits);
  98. + freebsd32_rt_metrics_in(&src->rtm_rmx, &dst->rtm_rmx);
  99. +}
  100. +
  101. +static void
  102. +freebsd32_rt_msghdr_out(struct rt_msghdr *src, struct rt_msghdr32 *dst)
  103. +{
  104. +
  105. + bzero(dst, sizeof(*dst));
  106. + /* CP(*src, *dst, rtm_msglen); */ /* updated separately */
  107. + CP(*src, *dst, rtm_version);
  108. + CP(*src, *dst, rtm_type);
  109. + CP(*src, *dst, rtm_index);
  110. + CP(*src, *dst, rtm_flags);
  111. + CP(*src, *dst, rtm_addrs);
  112. + CP(*src, *dst, rtm_pid);
  113. + CP(*src, *dst, rtm_seq);
  114. + CP(*src, *dst, rtm_errno);
  115. + CP(*src, *dst, rtm_fmask);
  116. + CP(*src, *dst, rtm_inits);
  117. + freebsd32_rt_metrics_out(&src->rtm_rmx, &dst->rtm_rmx);
  118. +}
  119. +
  120. +static int
  121. +freebsd32_rt_mspace_len_in(caddr_t cp, caddr_t cplim, int *buflen)
  122. +{
  123. + struct sockaddr *sa;
  124. + int i;
  125. +
  126. + for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) {
  127. + sa = (struct sockaddr *)cp;
  128. +
  129. + if (cp + sa->sa_len > cplim)
  130. + return (EINVAL);
  131. + cp += SA_SIZE32(sa);
  132. + *buflen += SA_SIZE(sa);
  133. + }
  134. + return (0);
  135. +}
  136. +
  137. +static int
  138. +freebsd32_rt_mspace_len_out(caddr_t cp, caddr_t cplim, int *buflen)
  139. +{
  140. + struct sockaddr *sa;
  141. + int i;
  142. +
  143. + for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) {
  144. + sa = (struct sockaddr *)cp;
  145. +
  146. + if (cp + sa->sa_len > cplim)
  147. + return (EINVAL);
  148. + cp += SA_SIZE(sa);
  149. + *buflen += SA_SIZE32(sa);
  150. + }
  151. + return (0);
  152. +}
  153. +
  154. +static int
  155. +freebsd32_rt_mspace_in(caddr_t cp, caddr_t cp64, caddr_t cplim)
  156. +{
  157. + struct sockaddr *sa;
  158. + int i;
  159. +
  160. + for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
  161. + sa = (struct sockaddr *)cp;
  162. +
  163. + if (cp + sa->sa_len > cplim)
  164. + return (EINVAL);
  165. + memcpy(cp64, cp, SA_SIZE32(sa));
  166. + cp += SA_SIZE32(sa);
  167. + cp64 += SA_SIZE(sa);
  168. + }
  169. + return (0);
  170. +}
  171. +
  172. +static int
  173. +freebsd32_rt_mspace_out(caddr_t cp, caddr_t cp32, caddr_t cplim)
  174. +{
  175. + struct sockaddr *sa;
  176. + int i;
  177. +
  178. + for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
  179. + sa = (struct sockaddr *)cp;
  180. +
  181. + if (cp + sa->sa_len > cplim)
  182. + return (EINVAL);
  183. + memcpy(cp32, cp, SA_SIZE(sa));
  184. + cp += SA_SIZE(sa);
  185. + cp32 += SA_SIZE32(sa);
  186. + }
  187. + return (0);
  188. +}
  189. +#endif
  190. +
  191. /*ARGSUSED*/
  192. static int
  193. route_output(struct mbuf *m, struct socket *so)
  194. @@ -573,6 +743,14 @@
  195. struct ifnet *ifp = NULL;
  196. union sockaddr_union saun;
  197. sa_family_t saf = AF_UNSPEC;
  198. + size_t rtmlen;
  199. +#ifdef COMPAT_FREEBSD32
  200. + struct rt_msghdr32 *rtm32 = NULL;
  201. + int len32 = 0, rt_mspace_len = 0, wrap32 = 0;
  202. +
  203. + if (SV_CURPROC_FLAG(SV_ILP32))
  204. + wrap32 = 1;
  205. +#endif
  206.  
  207. #define senderr(e) { error = e; goto flush;}
  208. if (m == NULL || ((m->m_len < sizeof(long)) &&
  209. @@ -581,17 +759,50 @@
  210. if ((m->m_flags & M_PKTHDR) == 0)
  211. panic("route_output");
  212. len = m->m_pkthdr.len;
  213. - if (len < sizeof(*rtm) ||
  214. +
  215. +#ifdef COMPAT_FREEBSD32
  216. + if (wrap32) {
  217. + rtmlen = sizeof(*rtm32);
  218. + len32 = len;
  219. + } else
  220. +#endif
  221. + rtmlen = sizeof(*rtm);
  222. +
  223. + if (len < rtmlen ||
  224. len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
  225. info.rti_info[RTAX_DST] = NULL;
  226. senderr(EINVAL);
  227. }
  228. - R_Malloc(rtm, struct rt_msghdr *, len);
  229. +
  230. +#ifdef COMPAT_FREEBSD32
  231. + if (wrap32) {
  232. + R_Malloc(rtm32, struct rt_msghdr32 *, len32);
  233. + if (rtm32 == NULL) {
  234. + info.rti_info[RTAX_DST] = NULL;
  235. + senderr(ENOBUFS);
  236. + }
  237. + m_copydata(m, 0, len32, (caddr_t)rtm32);
  238. + freebsd32_rt_mspace_len_in((caddr_t)(rtm32 + 1), len32 + (caddr_t)rtm32, &rt_mspace_len);
  239. + /* fixup len to alloc rtm of native size */
  240. + len = rt_mspace_len + sizeof(*rtm);
  241. + }
  242. +#endif
  243. + R_Zalloc(rtm, struct rt_msghdr *, len);
  244. if (rtm == NULL) {
  245. info.rti_info[RTAX_DST] = NULL;
  246. senderr(ENOBUFS);
  247. }
  248. - m_copydata(m, 0, len, (caddr_t)rtm);
  249. +
  250. +#ifdef COMPAT_FREEBSD32
  251. + if (wrap32) {
  252. + freebsd32_rt_msghdr_in(rtm32, rtm);
  253. + freebsd32_rt_mspace_in((caddr_t)(rtm32 + 1),
  254. + (caddr_t)(rtm + 1), (caddr_t)rtm32 + len32);
  255. + rtm->rtm_msglen = len;
  256. + } else
  257. +#endif
  258. + m_copydata(m, 0, len, (caddr_t)rtm);
  259. +
  260. if (rtm->rtm_version != RTM_VERSION) {
  261. info.rti_info[RTAX_DST] = NULL;
  262. senderr(EPROTONOSUPPORT);
  263. @@ -603,6 +814,16 @@
  264. info.rti_info[RTAX_DST] = NULL;
  265. senderr(EINVAL);
  266. }
  267. +/*
  268. + int i; uint16_t *j;
  269. +
  270. + for (i = 0; i * (int)sizeof(uint16_t) < len; i++) {
  271. + j = (uint16_t *)rtm;
  272. + if (i % 8 == 0)
  273. + printf("\n0x%04jx ", (uintmax_t)i*sizeof(uint16_t));
  274. + printf("%04x ", bswap16(j[i]));
  275. + }; printf("\n");
  276. +*/
  277. info.rti_flags = rtm->rtm_flags;
  278. if (info.rti_info[RTAX_DST] == NULL ||
  279. info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
  280. @@ -938,12 +1159,41 @@
  281. rp = sotorawcb(so);
  282. }
  283. if (rtm) {
  284. - m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
  285. - if (m->m_pkthdr.len < rtm->rtm_msglen) {
  286. - m_freem(m);
  287. - m = NULL;
  288. - } else if (m->m_pkthdr.len > rtm->rtm_msglen)
  289. - m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
  290. +#ifdef COMPAT_FREEBSD32
  291. + if (wrap32) {
  292. + int rt_mspace_len32;
  293. +
  294. + freebsd32_rt_mspace_len_out((caddr_t)(rtm + 1),
  295. + len + (caddr_t)rtm, &rt_mspace_len32);
  296. + len32 = rt_mspace_len32 + sizeof(*rtm32);
  297. + if (len32 > rtm32->rtm_msglen) {
  298. + struct rt_msghdr32 *new_rtm32;
  299. + R_Malloc(new_rtm32, struct rt_msghdr32 *, len32);
  300. + if (new_rtm32 == NULL)
  301. + senderr(ENOBUFS);
  302. + bcopy(rtm32, new_rtm32, rtm32->rtm_msglen);
  303. + Free(rtm32); rtm32 = new_rtm32;
  304. + }
  305. + freebsd32_rt_msghdr_out(rtm, rtm32);
  306. + rtm32->rtm_msglen = len32;
  307. + freebsd32_rt_mspace_out((caddr_t)(rtm + 1),
  308. + (caddr_t)(rtm32 + 1), (caddr_t)rtm + len);
  309. +
  310. + m_copyback(m, 0, rtm32->rtm_msglen, (caddr_t)rtm32);
  311. + if (m->m_pkthdr.len < rtm32->rtm_msglen) {
  312. + m_freem(m);
  313. + m = NULL;
  314. + } else if (m->m_pkthdr.len > rtm32->rtm_msglen)
  315. + m_adj(m, rtm32->rtm_msglen - m->m_pkthdr.len);
  316. + } else {
  317. +#endif
  318. + m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
  319. + if (m->m_pkthdr.len < rtm->rtm_msglen) {
  320. + m_freem(m);
  321. + m = NULL;
  322. + } else if (m->m_pkthdr.len > rtm->rtm_msglen)
  323. + m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
  324. + }
  325. }
  326. if (m) {
  327. M_SETFIB(m, so->so_fibnum);
  328. @@ -961,8 +1211,13 @@
  329. rt_dispatch(m, saf);
  330. }
  331. /* info.rti_info[RTAX_DST] (used above) can point inside of rtm */
  332. - if (rtm)
  333. + if (rtm) {
  334. Free(rtm);
  335. +#ifdef COMPAT_FREEBSD32
  336. + if (wrap32)
  337. + Free(rtm32);
  338. +#endif
  339. + }
  340. }
  341. return (error);
  342. #undef sa_equal
Add Comment
Please, Sign In to add comment