if_tap unaligned access problem

Maksim Yevmenkin maksim.yevmenkin at savvis.net
Fri Apr 29 11:36:05 PDT 2005


[...]

>>>I could try to port the changes netbsd made using m_copyup and
>>>send you the resulting patchfile. IPv4 has already been serviced by
>>>John-Mark Gurney in perforce. 
>>
>>having these changes in the tree is a good thing, but it will require 
>>more testing. maybe for now we could get away with simpler changes?
> 
> 
>>@@ -1342,12 +1342,15 @@
>> 		total = min(uio->uio_resid, len);
>> 	else
>> 		total = uio->uio_resid;
>>+	if (align >= MHLEN)
>>+		goto nospace;
>> 	if (total > MHLEN)
> 
> 
> Shouldn't this check be total + align > MHLEN?

ops. yes it should, thanks for catching this!

>> 		m_final = m_getcl(how, MT_DATA, M_PKTHDR);
>> 	else
>> 		m_final = m_gethdr(how, MT_DATA);
>> 	if (m_final == NULL)
>> 		goto nospace;
>>+	m_adj(m_final, align);
>> 	m_new = m_final;
>> 	while (progress < total) {
>> 		length = total - progress;

also, there is probably no good reason to call m_adj, we could just 
"m_final->m_data += align" like so

Index: uipc_mbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.147
diff -u -r1.147 uipc_mbuf.c
--- uipc_mbuf.c 17 Mar 2005 19:34:57 -0000      1.147
+++ uipc_mbuf.c 29 Apr 2005 18:31:51 -0000
@@ -1333,7 +1333,7 @@
  #endif

  struct mbuf *
-m_uiotombuf(struct uio *uio, int how, int len)
+m_uiotombuf(struct uio *uio, int how, int len, int align)
  {
         struct mbuf *m_new = NULL, *m_final = NULL;
         int progress = 0, error = 0, length, total;
@@ -1342,12 +1342,15 @@
                 total = min(uio->uio_resid, len);
         else
                 total = uio->uio_resid;
-       if (total > MHLEN)
+       if (align >= MHLEN)
+               goto nospace;
+       if (total + align > MHLEN)
                 m_final = m_getcl(how, MT_DATA, M_PKTHDR);
         else
                 m_final = m_gethdr(how, MT_DATA);
         if (m_final == NULL)
                 goto nospace;
+       m_final->m_data += align;
         m_new = m_final;
         while (progress < total) {
                 length = total - progress;

thanks,
max


More information about the freebsd-net mailing list