Making LLDP Work with Linux Bridge

Last week I described how I configured PVLAN on a Linux bridge. After checking the desired partial connectivity with ios_ping I wanted to verify it with LLDP neighbors. Ansible ios_facts module collects LLDP neighbor information, and it should be really easy using those facts to check whether port isolation works as expected.

Ansible playbook displaying LLDP neighbors on selected interface
- name: Display LLDP neighbors on selected interface
  hosts: all
  gather_facts: true
    target_interface: GigabitEthernet0/1
  - name: Display neighbors gathered with ios_facts
      var: ansible_net_neighbors[target_interface]

Alas, none of the routers saw any neighbors on the target interface.

Fortunately, I wasn’t the first one experiencing this problem. It turns out Linux bridge blocks packets sent to IEEE-reserved MAC addresses (MAC addresses used by LLDP, LACP, STP, 802.1X, PBB control plane), but you can change that behavior by modifying the group_fwd_mask system parameter.

You can find all the gory details in a blog post by Robin Gilijamse, what we need to do is to set group_fwd_mask to 0x4000. To do that we need to write the desired value into ‌/sys/class/net/device/bridge/group_fwd_mask. The device name is the Linux bridge name (not libvirt network name) and to find it, we need to use virsh net-info command.

Another boring task worth automating. Here’s the Bash script doing it (invoke it with libvirt network name).

bridge=$(virsh net-info ${network}|grep Bridge|awk '{ print $2 }')
echo "libvirt network ${network} is Linux bridge ${bridge}"
echo "... enabling LLDP on ${bridge}"
sudo sh -c "echo 0x4000 >/sys/class/net/${bridge}/bridge/group_fwd_mask"

After changing the group_fwd_mask, LLDP works like a charm:

LLDP neighbors on a hub-and-spoke PVLAN bridge

LLDP neighbors on a hub-and-spoke PVLAN bridge

More Information

Add comment