Fix minor bug in flow_extract().
authorBen Pfaff <blp@nicira.com>
Mon, 19 Jan 2009 18:53:03 +0000 (10:53 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 23 Jan 2009 22:05:43 +0000 (14:05 -0800)
We were treating 802.2 frames that were too short to have a SNAP header as
if they had a dl_type of 0, when really they were supposed to have a
dl_type of OFP_DL_TYPE_NOT_ETH_TYPE.

This bug probably didn't affect anything in practice, because it is very
unusual to have a 802.2 frame that is too short to have a SNAP header,
because any frame that goes over a physical wire will be padded out so
that it is longer than that.

lib/flow.c

index 571b71bbdd7249ac01c716632befc9b5d3023bc6..2145d5964fac71ae6a381e6169a8c80efb6418e9 100644 (file)
@@ -118,17 +118,20 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, struct flow *flow)
             flow->dl_type = eth->eth_type;
         } else {
             /* This is an 802.2 frame */
-            struct llc_snap_header *h = ofpbuf_at(&b, 0, sizeof *h);
-            if (h == NULL) {
+            struct llc_header *llc = ofpbuf_at(&b, 0, sizeof *llc);
+            struct snap_header *snap = ofpbuf_at(&b, sizeof *llc,
+                                                 sizeof *snap);
+            if (llc == NULL) {
                 return 0;
             }
-            if (h->llc.llc_dsap == LLC_DSAP_SNAP
-                && h->llc.llc_ssap == LLC_SSAP_SNAP
-                && h->llc.llc_cntl == LLC_CNTL_SNAP
-                && !memcmp(h->snap.snap_org, SNAP_ORG_ETHERNET,
-                           sizeof h->snap.snap_org)) {
-                flow->dl_type = h->snap.snap_type;
-                ofpbuf_pull(&b, sizeof *h);
+            if (snap
+                && llc->llc_dsap == LLC_DSAP_SNAP
+                && llc->llc_ssap == LLC_SSAP_SNAP
+                && llc->llc_cntl == LLC_CNTL_SNAP
+                && !memcmp(snap->snap_org, SNAP_ORG_ETHERNET,
+                           sizeof snap->snap_org)) {
+                flow->dl_type = snap->snap_type;
+                ofpbuf_pull(&b, LLC_SNAP_HEADER_LEN);
             } else {
                 flow->dl_type = htons(OFP_DL_TYPE_NOT_ETH_TYPE);
                 ofpbuf_pull(&b, sizeof(struct llc_header));