PERFORCE change 167413 for review

Bjoern A. Zeeb bz at FreeBSD.org
Sun Aug 16 19:43:40 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=167413

Change 167413 by bz at 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);
 }


More information about the p4-projects mailing list