Re: About 802.1Q tag

From: YongHyeon PYUN <pyunyh_at_gmail.com>
Date: Mon, 26 Nov 2012 17:10:40 +0900
On Mon, Nov 26, 2012 at 09:54:14AM +0900, Kohji Okuno wrote:
> 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.

Yes, your analysis looks correct.

> 
> 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	        }
Received on Mon Nov 26 2012 - 07:10:56 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:32 UTC