Date: Sun, 16 Aug 2009 19:43:40 GMT From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 167413 for review Message-ID: <200908161943.n7GJheCb012595@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=167413 Change 167413 by bz@bz_zoo on 2009/08/16 19:43:35 In send_output: - make sure that enough of the ip6 header is there before accessing it (just to be save). - rather than allocating (and not freeing) put dst on the stack for passing it to if_output. - return a proper error in each case rather than 0. In send_input: - allocate contigous memory for the entire payload as rtsock.c:rt_msg3() just copies it from that and cannot handle multiple mbufs as data input. We can free it once we return from rt_securendmsg() as rt_msg3() did another copy. We can later optimize this code path. Affected files ... .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.c#23 edit Differences ... ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.c#23 (text+ko) ==== @@ -20,11 +20,13 @@ #include <netinet6/send.h> #include <netinet6/in6_var.h> +MALLOC_DEFINE(M_SEND, "send", "Secure Neighbour Discovery"); + static int send_output(struct mbuf *m, struct ifnet *ifp, int direction) { struct ip6_hdr *ip6; - struct sockaddr_in6 *dst; + struct sockaddr_in6 dst; struct icmp6_hdr *icmp6; int icmp6len; @@ -51,76 +53,71 @@ } //icmp6_rip6_input(&m, *offp); + /* XXX-BZ TODO */ + return (ENOSYS); - break; case SND_OUT: + m = m_pullup(m, sizeof(struct ip6_hdr)); + if (!m) + return (ENOBUFS); ip6 = mtod(m, struct ip6_hdr *); - if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) m->m_flags |= M_MCAST; { - char ip6buf[INET6_ADDRSTRLEN]; - printf("XXX-AK, send.c: ifp=%p, xname=%s, dst=%s\n", ifp, ifp->if_xname, ip6_sprintf(ip6buf, &ip6->ip6_dst)); + char ip6buf[INET6_ADDRSTRLEN]; + printf("XXX-AK %s: ifp=%p, xname=%s, ip6->ip6_dst=%s\n", __func__, ifp, ifp->if_xname, ip6_sprintf(ip6buf, &ip6->ip6_dst)); } - dst = malloc (sizeof (struct sockaddr_in6), M_TEMP, M_NOWAIT); - bzero(dst, sizeof(*dst)); - dst->sin6_len = sizeof(struct sockaddr_in6); - dst->sin6_family = AF_INET6; - dst->sin6_addr = ip6->ip6_dst; - - { - char ip6buf[INET6_ADDRSTRLEN]; - printf("XXX-BZ, send.c: ifp=%p, xname=%s, dst=%s\n", ifp, ifp->if_xname, ip6_sprintf(ip6buf, &((struct sockaddr_in6 *)dst)->sin6_addr)); - } + bzero(&dst, sizeof(dst)); + dst.sin6_family = AF_INET6; + dst.sin6_len = sizeof(dst); + dst.sin6_addr = ip6->ip6_dst; /* - * From nd6.c: nd6_output_lle(). + * Output the packet as nd6.c:nd6_output_lle() would do. + * The mbuf is always consumed, so we do not have to care + * about that. */ - return (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, NULL); - //return (0); - break; + return ((*ifp->if_output)(ifp, m, (struct sockaddr *)&dst, + NULL)); default: - panic("Must be either SND_IN or SND_OUT."); + panic("%s: direction must be either SND_IN or SND_OUT.", __func__); } - - return (0); } static int send_input(struct mbuf *m, struct ifnet *ifp, int direction, int msglen) { - struct ip6_hdr *ip6; + u_int len; + void *data; if (m->m_flags & M_MCAST) - printf("send_input: M_MCAST packet\n"); + printf("%s: DEBUG %p M_MCAST packet\n", __func__, m); - ip6 = mtod(m, struct ip6_hdr *); + len = m_length(m, NULL); + if (len != msglen) + printf("XXX-BZ %s: (m)len=%u (ip6)msglen=%d", __func__, len, msglen); - struct mbuf *n = m_get(M_NOWAIT, MT_DATA); - if (direction == SND_IN) { - if (msglen > M_TRAILINGSPACE(m)) { - if (n == NULL) { - printf("rtsock.c: rt_msg3(), m_freem!\n"); - panic("n==NULL\n"); - return (1); - } - printf("send.c: bcopy!\n"); - bcopy(ip6, mtod(n, void *), msglen); - printf("send.c: bcopy ok!\n"); - n->m_len = msglen; - printf("send.c: msglen set up: n->m_len = data_len;\n"); - } - - ip6 = mtod(n, struct ip6_hdr *); + /* + * XXX-BZ we can save the alloc/free here if not relying on rtsock.c:rt_msg3() + * but using a version operating on mbuf-to-mbuf copy. + */ + data = malloc(msglen, M_SEND, M_NOWAIT); + if (data == NULL) { + m_freem(m); + return (ENOBUFS); } + + m_copydata(m, 0, msglen, data); /* * Send incoming or outgoing traffic to the user space either to be * protected (outgoing) or validated (incoming) according to rfc3971. */ - rt_securendmsg(ifp, direction, ip6, msglen); + rt_securendmsg(ifp, direction, data, msglen); + + free(data, M_SEND); return (0); }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908161943.n7GJheCb012595>
