I don't know if I ever posted these patches, but some time last year (looks
like about a year ago), I went and looked at bpf_filter() and noticed it
was sub optimal.  For example, in the kernel, for most TCP/IP filtering,
all the data is in the first mbuf (hence no problems with buflen) but the
m_xword, etc, functions still get called to extract data from the buffers.

The patches below "fix" this by changing the calling convention of
bpf_filter() to require that only kernel routines which are passing an
mbuf call it with buflen being 0.

If someone has the time, I'd be interested to know what, if any, speed
improvements this patch results in.

Darren

*** bpf_filter.c.orig   Sun Jun 18 03:26:43 2000
--- bpf_filter.c        Wed Jun 21 23:20:59 2000
***************
*** 80,95 ****
  #endif
  
  #ifdef KERNEL
! #include <sys/mbuf.h>
! #define MINDEX(len, m, k) \
  { \
!       len = m->m_len; \
!       while (k >= len) { \
!               k -= len; \
!               m = m->m_next; \
!               if (m == 0) \
                        return 0; \
!               len = m->m_len; \
        } \
  }
  
--- 94,108 ----
  #endif
  
  #ifdef KERNEL
! #define MINDEX(len, _m, _k) \
  { \
!       len = MLEN(m); \
!       while ((_k) >= len) { \
!               (_k) -= len; \
!               (_m) = (_m)->m_next; \
!               if ((_m) == 0) \
                        return 0; \
!               len = MLEN(m); \
        } \
  }
  
***************
*** 109,115 ****
                return EXTRACT_LONG(cp);
        }
        m0 = m->m_next;
!       if (m0 == 0 || m0->m_len + len - k < 4)
                goto bad;
        *err = 0;
        np = mtod(m0, u_char *);
--- 125,131 ----
                return EXTRACT_LONG(cp);
        }
        m0 = m->m_next;
!       if (m0 == 0 || MLEN(m0) + len - k < 4)
                goto bad;
        *err = 0;
        np = mtod(m0, u_char *);
***************
*** 159,164 ****
--- 175,182 ----
   * Execute the filter program starting at pc on the packet p
   * wirelen is the length of the original packet
   * buflen is the amount of data present
+  * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
+  * in all other cases, p is a pointer to a buffer and buflen is its size.
   */
  u_int
  bpf_filter(pc, p, wirelen, buflen)
***************
*** 170,175 ****
--- 188,204 ----
        register u_int32 A, X;
        register int k;
        int32 mem[BPF_MEMWORDS];
+ #ifdef        KERNEL
+       struct mbuf *m, *n;
+       int merr, len;
+ 
+       if (buflen == 0) {
+               m = (struct mbuf *)p;
+               p = mtod(m, u_char *);
+               buflen = MLEN(m);
+       } else
+               m = NULL;
+ #endif
  
        if (pc == 0)
                /*
***************
*** 188,194 ****
                        return 0;
  #else
                        abort();
! #endif                        
                case BPF_RET|BPF_K:
                        return (u_int)pc->k;
  
--- 217,223 ----
                        return 0;
  #else
                        abort();
! #endif
                case BPF_RET|BPF_K:
                        return (u_int)pc->k;
  
***************
*** 199,209 ****
                        k = pc->k;
                        if (k + sizeof(int32) > buflen) {
  #ifdef KERNEL
!                               int merr;
! 
!                               if (buflen != 0)
                                        return 0;
!                               A = m_xword((struct mbuf *)p, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
--- 228,236 ----
                        k = pc->k;
                        if (k + sizeof(int32) > buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               A = m_xword(m, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
***************
*** 218,228 ****
                        k = pc->k;
                        if (k + sizeof(short) > buflen) {
  #ifdef KERNEL
!                               int merr;
! 
!                               if (buflen != 0)
                                        return 0;
-                               A = m_xhalf((struct mbuf *)p, k, &merr);
                                continue;
  #else
                                return 0;
--- 245,255 ----
                        k = pc->k;
                        if (k + sizeof(short) > buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
!                                       return 0;
!                               A = m_xhalf(m, k, &merr);
!                               if (merr != 0)
                                        return 0;
                                continue;
  #else
                                return 0;
***************
*** 235,248 ****
                        k = pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               register struct mbuf *m;
!                               register int len;
! 
!                               if (buflen != 0)
                                        return 0;
!                               m = (struct mbuf *)p;
!                               MINDEX(len, m, k);
!                               A = mtod(m, u_char *)[k];
                                continue;
  #else
                                return 0;
--- 262,272 ----
                        k = pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               n = m;
!                               MINDEX(len, n, k);
!                               A = mtod(n, u_char *)[k];
                                continue;
  #else
                                return 0;
***************
*** 263,273 ****
                        k = X + pc->k;
                        if (k + sizeof(int32) > buflen) {
  #ifdef KERNEL
!                               int merr;
! 
!                               if (buflen != 0)
                                        return 0;
!                               A = m_xword((struct mbuf *)p, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
--- 287,295 ----
                        k = X + pc->k;
                        if (k + sizeof(int32) > buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               A = m_xword(m, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
***************
*** 282,292 ****
                        k = X + pc->k;
                        if (k + sizeof(short) > buflen) {
  #ifdef KERNEL
!                               int merr;
! 
!                               if (buflen != 0)
                                        return 0;
!                               A = m_xhalf((struct mbuf *)p, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
--- 304,312 ----
                        k = X + pc->k;
                        if (k + sizeof(short) > buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               A = m_xhalf(m, k, &merr);
                                if (merr != 0)
                                        return 0;
                                continue;
***************
*** 301,314 ****
                        k = X + pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               register struct mbuf *m;
!                               register int len;
! 
!                               if (buflen != 0)
                                        return 0;
!                               m = (struct mbuf *)p;
!                               MINDEX(len, m, k);
!                               A = mtod(m, u_char *)[k];
                                continue;
  #else
                                return 0;
--- 321,331 ----
                        k = X + pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               n = m;
!                               MINDEX(len, n, k);
!                               A = mtod(n, u_char *)[k];
                                continue;
  #else
                                return 0;
***************
*** 321,334 ****
                        k = pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               register struct mbuf *m;
!                               register int len;
! 
!                               if (buflen != 0)
                                        return 0;
!                               m = (struct mbuf *)p;
!                               MINDEX(len, m, k);
!                               X = (mtod(m, char *)[k] & 0xf) << 2;
                                continue;
  #else
                                return 0;
--- 338,348 ----
                        k = pc->k;
                        if (k >= buflen) {
  #ifdef KERNEL
!                               if (m == NULL)
                                        return 0;
!                               n = m;
!                               MINDEX(len, n, k);
!                               X = (mtod(n, char *)[k] & 0xf) << 2;
                                continue;
  #else
                                return 0;
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to