From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f177.google.com ([209.85.192.177]:33674 "EHLO mail-pf0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753878AbeCGAnH (ORCPT ); Tue, 6 Mar 2018 19:43:07 -0500 Received: by mail-pf0-f177.google.com with SMTP id q13so253056pff.0 for ; Tue, 06 Mar 2018 16:43:07 -0800 (PST) Subject: Re: "wrong" ifindex on received VLAN tagged packet? To: Lawrence Kreeger , netdev@vger.kernel.org References: From: David Ahern Message-ID: Date: Tue, 6 Mar 2018 17:43:04 -0700 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org List-ID: On 3/6/18 3:02 PM, Lawrence Kreeger wrote: > Hello, > > I'm trying to run mstpd on a per VLAN basis using one traditional > linux bridge per VLAN. I'm running it on kernel version 4.12.4. It > works fine for untagged frames, but I'm having a problem with VLAN > tagged BPDUs arriving on the socket with the ifindex of the bridge > itself, and not the VLAN tagged interface. For example, I have a > tagged interface eth0.100 connected to the bridge "vlan100". When > packets arrive, they have the ifindex of vlan100, which mstpd doesn't > recognize as a valid spanning tree interface, so it drops them. Is > there something needed to be set in the kernel to get the ifindex of > eth0.100 instead? This is how mstpd opens the raw socket: > > > /* Berkeley Packet filter code to filter out spanning tree packets. > from tcpdump -s 1152 -dd stp > */ > static struct sock_filter stp_filter[] = { > { 0x28, 0, 0, 0x0000000c }, > { 0x25, 3, 0, 0x000005dc }, > { 0x30, 0, 0, 0x0000000e }, > { 0x15, 0, 1, 0x00000042 }, > { 0x6, 0, 0, 0x00000480 }, > { 0x6, 0, 0, 0x00000000 }, > }; > > /* > * Open up a raw packet socket to catch all 802.2 packets. > * and install a packet filter to only see STP (SAP 42) > * > * Since any bridged devices are already in promiscious mode > * no need to add multicast address. > */ > int packet_sock_init(void) > { > int s; > struct sock_fprog prog = > { > .len = sizeof(stp_filter) / sizeof(stp_filter[0]), > .filter = stp_filter, > }; > > s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_2)); try ETH_P_ALL > if(s < 0) > { > ERROR("socket failed: %m"); > return -1; > } > > if(setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) > ERROR("setsockopt packet filter failed: %m"); > else if(fcntl(s, F_SETFL, O_NONBLOCK) < 0) > ERROR("fcntl set nonblock failed: %m"); > else > { > packet_event.fd = s; > packet_event.handler = packet_rcv; And then packet_rcv using recvfrom: struct sockaddr_ll sll; char buf[4096]; socklen_t alen; int len; alen = sizeof(sll); len = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&sll, &alen); And sll.sll_ifindex will show vlan device indices. > > if(0 == add_epoll(&packet_event)) > return 0; > } > > close(s); > return -1; > } > > Thanks, Larry >