From owner-freebsd-bugs@FreeBSD.ORG Fri Oct 3 12:00:11 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 727F610656A0 for ; Fri, 3 Oct 2008 12:00:11 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 4E4B18FC1C for ; Fri, 3 Oct 2008 12:00:11 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m93C0BhP072058 for ; Fri, 3 Oct 2008 12:00:11 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m93C0B9S072056; Fri, 3 Oct 2008 12:00:11 GMT (envelope-from gnats) Resent-Date: Fri, 3 Oct 2008 12:00:11 GMT Resent-Message-Id: <200810031200.m93C0B9S072056@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Serge Potapov Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 42B51106568A for ; Fri, 3 Oct 2008 11:57:21 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 309E68FC16 for ; Fri, 3 Oct 2008 11:57:21 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id m93BvK6c039707 for ; Fri, 3 Oct 2008 11:57:20 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id m93BvK5x039706; Fri, 3 Oct 2008 11:57:20 GMT (envelope-from nobody) Message-Id: <200810031157.m93BvK5x039706@www.freebsd.org> Date: Fri, 3 Oct 2008 11:57:20 GMT From: Serge Potapov To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/127815: if_gif does not set vlan attributes from EtherIP encapsulated 802.1 packets X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Oct 2008 12:00:11 -0000 >Number: 127815 >Category: kern >Synopsis: if_gif does not set vlan attributes from EtherIP encapsulated 802.1 packets >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Oct 03 12:00:10 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Serge Potapov >Release: 7.1-BETA1 >Organization: Smart Telecom >Environment: FreeBSD test89.smartspb.net 7.1-BETA FreeBSD 7.1-BETA #1: Thu Oct 2 12:36:03 MSD 2008 root@test89.smartspb.net:/usr/obj/usr/src/sys/K7_LINAS_SRV_SMP i386 >Description: vlan2, mac2 -> interface2 vlan3, mac1 -> interface1 and so on. When gif interface receives EtherIP encapsulating 802.1Q packet it does not set m->m_pkthdr.ether_vtag and m->m_flags |= M_VLANTAG. Chain: ether<->if_bridge<->gif<->gif<->if_bridge<->ether transmits vlan tagged packets properly, but if_bridge bridge stores all MAC addresses learned from gif side in vlan1. In point-to-multipoint environment unicast 802.1Q (vlan_tag != 1) packets received from physical ethernet interface will be always sent over all gif interfaces attached to if_bridge. >How-To-Repeat: Simple, but need a lot of equipment. = | em0 +------+ em1 fxp0 +-------+ +--------+ CPE1 +-----------+ HOST1 | | $ip1 +------+ +-------+ | | em0 +------+ em1 fxp0 +-------+ +--------+ CPE2 +-----------+ HOST2 | | $ip3 +------+ +-------+ | | em0 +------+ em1 fxp0 +-------+ +--------+ CPE3 +-----------| HOST3 | | $ip3 +------+ +-------+ = CPE1: ifconfig bridge0 create; ifconfig em1 up; ifconfig bridge0 addm em1 up ifconfig gif2 create; ifconfig gif2 tunnel $ip1 $ip2 ifconfig bridge0 addm gif2; ifconfig bridge0 private gif2 ifconfig gif3 create; ifconfig gif3 tunnel $ip1 $ip3 ifconfig bridge0 addm gif3; ifconfig bridge0 private gif3 CPE2: ifconfig bridge0 create ifconfig em1 up; ifconfig bridge0 addm1 up ifconfig gif1 create; ifconfig gif1 tunnel $ip2 $ip1 ifconfig bridge0 addm gif1; ifconfig bridge0 private gif1 ifconfig gif3 create; ifconfig gif3 tunnel $ip2 $ip3 ifconfig bridge0 addm gif3; ifconfig bridge0 private gif3 CPE3: ifconfig bridge0 create ifconfig em1 up; ifconfig bridge0 addm1 up ifconfig gif1 create; ifconfig gif1 tunnel $ip3 $ip1 ifconfig bridge0 addm gif1; ifconfig bridge0 private gif1 ifconfig gif2 create; ifconfig gif2 tunnel $ip3 $ip2 ifconfig bridge0 addm gif2; ifconfig bridge0 private gif2 =================================================================== With plain 802.1 ethernet all works fine (thanks for private flag). No extra traffic, no loops. Almost poor man's VPLS. But after: HOST1: ifconfig fxp0 up ifconfig vlan5 create ifconfig vlan5 10.10.10.1/24 vlan 5 vlandev fxp0 HOST2: ifconfig fxp0 up ifconfig vlan5 create ifconfig vlan5 10.10.10.2/24 vlan 5 vlandev fxp0 ping 10.10.10.1 CPE2 will send all icmp requests received on em1 over gif1 and gif3 [waste] CPE1 will sens all icmp replies received on em0 over gif2 and gif3 [waste] CPE3 will receive icmp requests on gif2 and replies on gif1 and send all packets to em1. >Fix: Patch attached. Not sure about proper place. After patching vlan MACs stored properly and bridge woriking right. Not tested too much. Patch attached with submission follows: --- /sys/net/if_gif.c.orig 2008-10-03 14:18:50.000000000 +0400 +++ /sys/net/if_gif.c 2008-10-03 11:43:48.000000000 +0400 @@ -81,6 +81,7 @@ #include #include +#include #include #include @@ -560,6 +561,31 @@ m->m_flags |= M_MCAST; ifp->if_imcasts++; } + /* Check vlan tagging on received frame. */ + /* Probably should be moved somewhere up. */ + if (ntohs(eh->ether_type) == ETHERTYPE_VLAN) { + /* Copy from if_ethersubr.c */ + struct ether_vlan_header *evl; + if (m->m_len < sizeof(*evl) && + (m = m_pullup(m, sizeof(*evl))) == NULL) { +#ifdef DIAGNOSTIC + if_printf(ifp, "cannot pullup VLAN header\n"); +#endif + ifp->if_ierrors++; + m_freem(m); + return; + } + + evl = mtod(m, struct ether_vlan_header *); + m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag); + m->m_flags |= M_VLANTAG; + + bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN, + ETHER_HDR_LEN - ETHER_TYPE_LEN); + m_adj(m, ETHER_VLAN_ENCAP_LEN); + /* End of copy */ + } + BRIDGE_INPUT(ifp, m); if (m != NULL && ifp != oldifp) { >Release-Note: >Audit-Trail: >Unformatted: