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           }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[email protected]"

Reply via email to