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