summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/pfmod.c
diff options
context:
space:
mode:
authordg199075 <none@none>2006-09-19 11:16:27 -0700
committerdg199075 <none@none>2006-09-19 11:16:27 -0700
commit605445d5657096e69d948ccb554c9ff024fa34df (patch)
treec0acbb1d49d8259bf1a104d24f427270905e955c /usr/src/uts/common/io/pfmod.c
parent8bc68872f6b178bf5e1d324c663e29fb6ccb1eab (diff)
downloadillumos-gate-605445d5657096e69d948ccb554c9ff024fa34df.tar.gz
PSARC/2006/358 VLAN Observability Enhancement
4095699 snoop: add support for 802.1Q VLAN tagging 6292043 DL_PROMISC_SAP should see *all* traffic, not just untagged traffic on GLDv2 links 6306794 GLDv2 drivers incorrectly strip the VLAN tag in raw mode 6309233 GLDv3 drivers incorrectly process VLAN packets in raw mode 6375633 GLDv2 processes DL_PROMISC{ON,OFF}_REQ incorrectly 6425678 DL_PROMISC_SAP should make all VLAN traffic visible on physical GLDv3 links 6434082 Enhance snoop's VLAN filtering capability 6434130 i_dls_ether_header() doesn't generate VLAN header when priority is non-zero 6436003 QoS should be supported on non VLAN streams as well 6438679 GLDv3 doesn't respect QoS priorities in some cases 6442753 GLDv2/GLDv3 has several VLAN packet processing issues 6453746 Change definition of enprintf in pfmod.c 6457476 GLDv2 kstats are not MT-protected, could cause missing increment in some cases 6464397 mac_header_{cook,uncook}() failure can cause a message to be freed twice
Diffstat (limited to 'usr/src/uts/common/io/pfmod.c')
-rw-r--r--usr/src/uts/common/io/pfmod.c126
1 files changed, 66 insertions, 60 deletions
diff --git a/usr/src/uts/common/io/pfmod.c b/usr/src/uts/common/io/pfmod.c
index 8f13b47877..9a7d66e995 100644
--- a/usr/src/uts/common/io/pfmod.c
+++ b/usr/src/uts/common/io/pfmod.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -343,7 +342,9 @@ pfioctl(queue_t *wq, mblk_t *mp)
struct Pf_ext_packetfilt *upfp;
struct packetfilt *opfp;
ushort_t *fwp;
- int maxoff, arg;
+ int arg;
+ int maxoff = 0;
+ int maxoffreg = 0;
struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
int error;
@@ -406,7 +407,6 @@ pfioctl(queue_t *wq, mblk_t *mp)
* body to pull up. This code depends on the
* filter encoding.
*/
- maxoff = 0;
for (fwp = pfp->pf_Filter; fwp < pfp->pf_FilterEnd; fwp++) {
arg = *fwp & ((1 << ENF_NBPA) - 1);
switch (arg) {
@@ -415,7 +415,16 @@ pfioctl(queue_t *wq, mblk_t *mp)
maxoff = arg;
break;
+ case ENF_LOAD_OFFSET:
+ /* Point to the offset */
+ fwp++;
+ if (*fwp > maxoffreg)
+ maxoffreg = *fwp;
+ break;
+
case ENF_PUSHLIT:
+ case ENF_BRTR:
+ case ENF_BRFL:
/* Skip over the literal. */
fwp++;
break;
@@ -426,6 +435,7 @@ pfioctl(queue_t *wq, mblk_t *mp)
case ENF_PUSHFF00:
case ENF_PUSH00FF:
case ENF_NOPUSH:
+ case ENF_POP:
break;
}
}
@@ -433,8 +443,7 @@ pfioctl(queue_t *wq, mblk_t *mp)
/*
* Convert word offset to length in bytes.
*/
- pfp->pf_PByteLen = (maxoff + 1) * sizeof (ushort_t);
-
+ pfp->pf_PByteLen = (maxoff + maxoffreg + 1) * sizeof (ushort_t);
miocack(wq, mp, 0, 0);
break;
@@ -448,23 +457,10 @@ pfioctl(queue_t *wq, mblk_t *mp)
/* #define INNERDEBUG 1 */
#ifdef INNERDEBUG
-#define enprintf(flags) if (enDebug & (flags)) printf
-
-/*
- * Symbolic definitions for enDebug flag bits
- * ENDBG_TRACE should be 1 because it is the most common
- * use in the code, and the compiler generates faster code
- * for testing the low bit in a word.
- */
-
-#define ENDBG_TRACE 1 /* trace most operations */
-#define ENDBG_DESQ 2 /* trace descriptor queues */
-#define ENDBG_INIT 4 /* initialization info */
-#define ENDBG_SCAV 8 /* scavenger operation */
-#define ENDBG_ABNORM 16 /* abnormal events */
-
-int enDebug = /* ENDBG_ABNORM | ENDBG_INIT | ENDBG_TRACE */ -1;
-#endif /* INNERDEBUG */
+#define enprintf(a) printf a
+#else
+#define enprintf(a)
+#endif
/*
* Apply the packet filter given by pfp to the packet given by
@@ -493,15 +489,13 @@ FilterPacket(struct packdesc *pp, struct epacketfilt *pfp)
ushort_t *fpe;
unsigned op;
unsigned arg;
+ unsigned offreg = 0;
ushort_t stack[ENMAXFILTERS+1];
fp = &pfp->pf_Filter[0];
fpe = pfp->pf_FilterEnd;
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("FilterPacket(%p, %p, %p, %p):\n",
- pp, pfp, fp, fpe);
-#endif
+ enprintf(("FilterPacket(%p, %p, %p, %p):\n", pp, pfp, fp, fpe));
/*
* Push TRUE on stack to start. The stack size is chosen such
@@ -525,14 +519,12 @@ FilterPacket(struct packdesc *pp, struct epacketfilt *pfp)
* if it were less than ENF_PUSHWORD before,
* it would now be huge.
*/
- if (arg < maxhdr)
- *--sp = pp->pd_hdr[arg];
- else if (arg < maxword)
- *--sp = pp->pd_body[arg - maxhdr];
+ if (arg + offreg < maxhdr)
+ *--sp = pp->pd_hdr[arg + offreg];
+ else if (arg + offreg < maxword)
+ *--sp = pp->pd_body[arg - maxhdr + offreg];
else {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>0(len)\n");
-#endif
+ enprintf(("=>0(len)\n"));
return (0);
}
break;
@@ -554,14 +546,42 @@ FilterPacket(struct packdesc *pp, struct epacketfilt *pfp)
case ENF_PUSH00FF:
*--sp = 0x00ff;
break;
+ case ENF_LOAD_OFFSET:
+ offreg = *fp++;
+ break;
+ case ENF_BRTR:
+ if (*sp != 0)
+ fp += *fp;
+ else
+ fp++;
+ if (fp >= fpe) {
+ enprintf(("BRTR: fp>=fpe\n"));
+ return (0);
+ }
+ break;
+ case ENF_BRFL:
+ if (*sp == 0)
+ fp += *fp;
+ else
+ fp++;
+ if (fp >= fpe) {
+ enprintf(("BRFL: fp>=fpe\n"));
+ return (0);
+ }
+ break;
+ case ENF_POP:
+ ++sp;
+ if (sp > &stack[ENMAXFILTERS]) {
+ enprintf(("stack underflow\n"));
+ return (0);
+ }
+ break;
case ENF_NOPUSH:
break;
}
if (sp < &stack[2]) { /* check stack overflow: small yellow zone */
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>0(--sp)\n");
-#endif
+ enprintf(("=>0(--sp)\n"));
return (0);
}
@@ -573,18 +593,14 @@ FilterPacket(struct packdesc *pp, struct epacketfilt *pfp)
* on stack to evaluate.
*/
if (sp > &stack[ENMAXFILTERS-2]) {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>0(sp++)\n");
-#endif
+ enprintf(("=>0(sp++)\n"));
return (0);
}
arg = *sp++;
switch (op) {
default:
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>0(def)\n");
-#endif
+ enprintf(("=>0(def)\n"));
return (0);
case opx(ENF_AND):
*sp &= arg;
@@ -618,40 +634,30 @@ FilterPacket(struct packdesc *pp, struct epacketfilt *pfp)
case opx(ENF_COR):
if (*sp++ == arg) {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>COR %x\n", *sp);
-#endif
+ enprintf(("=>COR %x\n", *sp));
return (1);
}
break;
case opx(ENF_CAND):
if (*sp++ != arg) {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>CAND %x\n", *sp);
-#endif
+ enprintf(("=>CAND %x\n", *sp));
return (0);
}
break;
case opx(ENF_CNOR):
if (*sp++ == arg) {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>COR %x\n", *sp);
-#endif
+ enprintf(("=>COR %x\n", *sp));
return (0);
}
break;
case opx(ENF_CNAND):
if (*sp++ != arg) {
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>CNAND %x\n", *sp);
-#endif
+ enprintf(("=>CNAND %x\n", *sp));
return (1);
}
break;
}
}
-#ifdef INNERDEBUG
- enprintf(ENDBG_TRACE)("=>%x\n", *sp);
-#endif
+ enprintf(("=>%x\n", *sp));
return (*sp);
}