About 802.1Q tag
Kohji Okuno
okuno.kohji at jp.panasonic.com
Mon Nov 26 01:15:52 UTC 2012
Hi,
Would someone check the following code?
If the hardware do not process an 802.1Q tag, the kernel repacks mbuf
in line 578-580. But, `struct ether_header *eh' was assigned at line 484.
And, in line 611-637, because of the kernel refers old eh pointer, the
kernel will misjudges its ether packet.
I think that `eh = mtod(m, struct ether_header *);' is needed after
line 580.
Thanks,
Kohji Okuno
sys/net/if_ethersubr.c:
448 static void
449 ether_input_internal(struct ifnet *ifp, struct mbuf *m)
450 {
451 struct ether_header *eh;
484 eh = mtod(m, struct ether_header *);
554 /*
555 * If the hardware did not process an 802.1Q tag, do this now,
556 * to allow 802.1P priority frames to be passed to the main input
557 * path correctly.
558 * TODO: Deal with Q-in-Q frames, but not arbitrary nesting levels.
559 */
560 if ((m->m_flags & M_VLANTAG) == 0 && etype == ETHERTYPE_VLAN) {
578 bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
579 ETHER_HDR_LEN - ETHER_TYPE_LEN);
580 m_adj(m, ETHER_VLAN_ENCAP_LEN);
581 }
610
611 #if defined(INET) || defined(INET6)
612 /*
613 * Clear M_PROMISC on frame so that carp(4) will see it when the
614 * mbuf flows up to Layer 3.
615 * FreeBSD's implementation of carp(4) uses the inprotosw
616 * to dispatch IPPROTO_CARP. carp(4) also allocates its own
617 * Ethernet addresses of the form 00:00:5e:00:01:xx, which
618 * is outside the scope of the M_PROMISC test below.
619 * TODO: Maintain a hash table of ethernet addresses other than
620 * ether_dhost which may be active on this ifp.
621 */
622 if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
623 m->m_flags &= ~M_PROMISC;
624 } else
625 #endif
626 {
627 /*
628 * If the frame received was not for our MAC address, set the
629 * M_PROMISC flag on the mbuf chain. The frame may need to
630 * be seen by the rest of the Ethernet input path in case of
631 * re-entry (e.g. bridge, vlan, netgraph) but should not be
632 * seen by upper protocol layers.
633 */
634 if (!ETHER_IS_MULTICAST(eh->ether_dhost) &&
635 bcmp(IF_LLADDR(ifp), eh->ether_dhost, ETHER_ADDR_LEN) != 0)
636 m->m_flags |= M_PROMISC;
637 }
More information about the freebsd-current
mailing list