Re: "wrong" ifindex on received VLAN tagged packet?

2018-03-12 Thread David Ahern
On 3/6/18 5:27 PM, Lawrence Kreeger wrote:
> Using ETH_P_ALL instead of ETH_P_802_2, is causing mstpd to get 3
> copies of the same BPDU.  One from eth0, one from eth0.100, and
> another from vlan100 (the bridge).
> mstpd will drop the one from vlan100, but since there is also an
> instance of spanning tree running on the native VLAN, there is now no
> way to differentiate BPDUs coming in
> tagged vs untagged because they all show up with eth0.  So, there
> isn't some kernel knob to get the BPDUs to only come from eth0.100?

not that I am aware of. You could bind your socket or program to
eth0.100, but I suspect you actually have more than the one vlan
interface coming into the bridge that you want to snoop.


Re: "wrong" ifindex on received VLAN tagged packet?

2018-03-06 Thread Lawrence Kreeger
Using ETH_P_ALL instead of ETH_P_802_2, is causing mstpd to get 3
copies of the same BPDU.  One from eth0, one from eth0.100, and
another from vlan100 (the bridge).
mstpd will drop the one from vlan100, but since there is also an
instance of spanning tree running on the native VLAN, there is now no
way to differentiate BPDUs coming in
tagged vs untagged because they all show up with eth0.  So, there
isn't some kernel knob to get the BPDUs to only come from eth0.100?

On Tue, Mar 6, 2018 at 4:43 PM, David Ahern  wrote:
> 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, 0x000c },
>> { 0x25, 3, 0, 0x05dc },
>> { 0x30, 0, 0, 0x000e },
>> { 0x15, 0, 1, 0x0042 },
>> { 0x6, 0, 0, 0x0480 },
>> { 0x6, 0, 0, 0x },
>> };
>>
>> /*
>>  * 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, , 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 *), );
>
> And sll.sll_ifindex will show vlan device indices.
>
>
>>
>> if(0 == add_epoll(_event))
>> return 0;
>> }
>>
>> close(s);
>> return -1;
>> }
>>
>> Thanks, Larry
>>
>


Re: "wrong" ifindex on received VLAN tagged packet?

2018-03-06 Thread David Ahern
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, 0x000c },
> { 0x25, 3, 0, 0x05dc },
> { 0x30, 0, 0, 0x000e },
> { 0x15, 0, 1, 0x0042 },
> { 0x6, 0, 0, 0x0480 },
> { 0x6, 0, 0, 0x },
> };
> 
> /*
>  * 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, , 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 *), );

And sll.sll_ifindex will show vlan device indices.


> 
> if(0 == add_epoll(_event))
> return 0;
> }
> 
> close(s);
> return -1;
> }
> 
> Thanks, Larry
> 



"wrong" ifindex on received VLAN tagged packet?

2018-03-06 Thread Lawrence Kreeger
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, 0x000c },
{ 0x25, 3, 0, 0x05dc },
{ 0x30, 0, 0, 0x000e },
{ 0x15, 0, 1, 0x0042 },
{ 0x6, 0, 0, 0x0480 },
{ 0x6, 0, 0, 0x },
};

/*
 * 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));
if(s < 0)
{
ERROR("socket failed: %m");
return -1;
}

if(setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, , 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;

if(0 == add_epoll(_event))
return 0;
}

close(s);
return -1;
}

Thanks, Larry