IGMP Snooping

IGMP Snooping constrains IPv4 multicast forwarding to ports with active listeners. The VelocitySP implementation covers Lightweight IGMPv3 (RFC 5790) with backward compatibility for IGMPv2 (RFC 2236). Configuration and status are exposed via the RFC 9166 YANG model for IGMP and MLD Snooping, accessed through CORECONF/CoAP.

An IGMP snooping instance is a control-plane-protocol entry of type igmp-snooping. Each VLAN is bound to at most one instance, and each instance is bound to at most one VLAN (1:1 binding) via the bridge-vlan configuration.

1. Example Topology

The examples below assume one multicast source and two receivers, all on the same VLAN. Without snooping the source’s stream would be flooded to every member port; with snooping enabled the switch forwards each group’s traffic only to ports that have actually reported a listener for it.

                        +--------------------------+
                        |                          |
   Multicast source --- | port 10                  |
   (eth_yellow)         |                          |
                        |     Switch (DUT)         |
                        |     VLAN 100             |
                        |     IGMP instance "igmp1"|
   Receiver A       --- | port 9                   |
   (eth_red, joins      |                          |
    239.1.1.1)          |                          |
                        |                          |
   Receiver B       --- | port 8                   |
   (eth_blue, joins     |                          |
    239.1.1.2)          |                          |
                        +--------------------------+

The IPATCHes that follow use this topology: VID 100, instance igmp1, ports 8, 9, 10 are bridge members.

2. Configure Bridge Ports

Each port participating in IGMP snooping is configured as a C-VLAN bridge port with PVID=100.

IPATCH request message:

- ? "/ietf-interfaces:interfaces/interface[name='10']/\
     ieee802-dot1q-bridge:bridge-port/port-type"
  : ieee802-dot1q-bridge:c-vlan-bridge-port

- ? "/ietf-interfaces:interfaces/interface[name='10']/\
     ieee802-dot1q-bridge:bridge-port/pvid"
  : 100

- ? "/ietf-interfaces:interfaces/interface[name='10']/\
     ieee802-dot1q-bridge:bridge-port/acceptable-frame"
  : admit-all-frames


- ? "/ietf-interfaces:interfaces/interface[name='9']/\
     ieee802-dot1q-bridge:bridge-port/port-type"
  : ieee802-dot1q-bridge:c-vlan-bridge-port

- ? "/ietf-interfaces:interfaces/interface[name='9']/\
     ieee802-dot1q-bridge:bridge-port/pvid"
  : 100

- ? "/ietf-interfaces:interfaces/interface[name='9']/\
     ieee802-dot1q-bridge:bridge-port/acceptable-frame"
  : admit-all-frames


- ? "/ietf-interfaces:interfaces/interface[name='8']/\
     ieee802-dot1q-bridge:bridge-port/port-type"
  : ieee802-dot1q-bridge:c-vlan-bridge-port

- ? "/ietf-interfaces:interfaces/interface[name='8']/\
     ieee802-dot1q-bridge:bridge-port/pvid"
  : 100

- ? "/ietf-interfaces:interfaces/interface[name='8']/\
     ieee802-dot1q-bridge:bridge-port/acceptable-frame"
  : admit-all-frames

3. Create VLAN

Create VID 100 with the topology ports as untagged members.

IPATCH request message:

- ? "/ieee802-dot1q-bridge:bridges/bridge[name='b0']/component[name='c0']/\
     filtering-database/vlan-registration-entry"
  : database-id: 0
    vids: '100'
    entry-type: static
    port-map:
    - port-ref: 10
      static-vlan-registration-entries:
        vlan-transmitted: untagged
    - port-ref: 9
      static-vlan-registration-entries:
        vlan-transmitted: untagged
    - port-ref: 8
      static-vlan-registration-entries:
        vlan-transmitted: untagged

4. Create and Configure IGMP Snooping Instance

A snooping instance is created and configured in one IPATCH. The control-plane-protocol entry is added together with its igmp-snooping-instance container; available configuration leafs:

  • enabled — enable/disable snooping on this instance

  • igmp-version — 2 or 3 (IGMPv2 or IGMPv3; IGMPv1 is not supported)

  • send-query — enable the active querier role

  • robustness-variable — protocol robustness (default 2)

  • query-interval — seconds between general queries (default 125)

  • query-max-response-time — max response delay in seconds (default 10)

  • last-member-query-interval — seconds between GSQ retransmissions

  • querier-source — IPv4 source address for generated queries

IPATCH request message:

- ? "/ietf-routing:routing/control-plane-protocols/control-plane-protocol"
  : type: ietf-igmp-mld-snooping:igmp-snooping
    name: igmp1
    ietf-igmp-mld-snooping:igmp-snooping-instance:
      enabled: true
      send-query: false
      igmp-version: 3
      robustness-variable: 2
      query-interval: 125
      query-max-response-time: 100
      last-member-query-interval: 10

FETCH request message:

- "/ietf-routing:routing/control-plane-protocols/\
   control-plane-protocol[type='ietf-igmp-mld-snooping:igmp-snooping'][name='igmp1']/\
   ietf-igmp-mld-snooping:igmp-snooping-instance"

FETCH response message:

- ? "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/\
     ietf-igmp-mld-snooping:igmp-snooping-instance"
  : enabled: true
    send-query: false
    last-member-query-interval: 10
    query-interval: 125
    query-max-response-time: 100
    robustness-variable: 2
    igmp-version: 3
    entries-count: 0

5. Bind VLAN to Snooping Instance

Each VLAN that should participate in IGMP snooping must be bound to an instance. The binding is done via the igmp-snooping-instance leaf in the bridge-vlan configuration.

IPATCH request message:

- ? "/ieee802-dot1q-bridge:bridges/bridge[name='b0']/component[name='c0']/\
     bridge-vlan/vlan"
  : vid: 100
    ietf-igmp-mld-snooping:igmp-snooping-instance: igmp1

6. Retrieve Snooping Status

The snooping status includes entries-count, multicast router interfaces, and the group/source table. The response below is captured with one listener joined, so it shows a populated group table; expire and up-time are timers and are shown with representative values.

FETCH request message:

- "/ietf-routing:routing/control-plane-protocols/\
   control-plane-protocol[type='ietf-igmp-mld-snooping:igmp-snooping'][name='igmp1']/\
   ietf-igmp-mld-snooping:igmp-snooping-instance"

FETCH response message:

- ? "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/\
     ietf-igmp-mld-snooping:igmp-snooping-instance"
  : enabled: true
    send-query: false
    last-member-query-interval: 10
    query-interval: 125
    query-max-response-time: 100
    robustness-variable: 2
    igmp-version: 3
    entries-count: 1
    group:
    - address: 239.1.1.1
      mac-address: 01-00-5E-01-01-01
      expire: 258
      up-time: 2
      last-reporter: 192.168.1.10

7. Delete IGMP Snooping Instance

The instance is deleted by setting the control-plane-protocol entry to null.

IPATCH request message:

- ? "/ietf-routing:routing/control-plane-protocols/\
     control-plane-protocol[type='ietf-igmp-mld-snooping:igmp-snooping'][name='igmp1']"
  :

8. Worked Example: ASM Join with mcjoin

This walks through a typical Any-Source Multicast (ASM) scenario on the topology above. The receiver joins group 239.1.1.1 with mcjoin, the source sends UDP packets to that group, and snooping confines the stream to the receiver’s port.

Each PC NIC is moved into its own network namespace so the host kernel does not auto-route the multicast traffic between them.

8.1. 1. Receiver joins (port 9 / eth_red)

ip netns add igmp_dst
ip link set eth_red netns igmp_dst
ip netns exec igmp_dst ip link set eth_red up
ip netns exec igmp_dst ip addr add 10.0.0.2/24 dev eth_red
ip netns exec igmp_dst ip route add 224.0.0.0/4 dev eth_red

# Join (*,G) and listen on UDP 5001 — mcjoin emits an IGMPv3 IS_EX report
ip netns exec igmp_dst \
    mcjoin -i eth_red -p 5001 -W 25 "239.1.1.1"

8.2. 2. Verify the switch learnt the group

The IGMPv3 report creates a (*, 239.1.1.1) entry on VID 100 bound to ingress port 9. Send the FETCH shown in Retrieve Snooping Status; the response is:

- ? "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/\
     ietf-igmp-mld-snooping:igmp-snooping-instance"
  : enabled: true
    send-query: false
    last-member-query-interval: 10
    query-interval: 125
    query-max-response-time: 100
    robustness-variable: 2
    igmp-version: 3
    entries-count: 1
    group:
    - address: 239.1.1.1
      mac-address: 01-00-5E-01-01-01
      expire: 258
      up-time: 2
      last-reporter: 192.168.1.10

8.3. 3. Source transmits (port 10 / eth_yellow)

ip netns add igmp_src
ip link set eth_yellow netns igmp_src
ip netns exec igmp_src ip link set eth_yellow up
ip netns exec igmp_src ip addr add 10.0.0.1/24 dev eth_yellow
ip netns exec igmp_src ip route add 224.0.0.0/4 dev eth_yellow

# 5000 packets at 1 ms interval to UDP 5001
ip netns exec igmp_src \
    mcjoin -s -i eth_yellow -f 1 -c 5000 -p 5001 "239.1.1.1"

8.4. 4. Expected behaviour

  • Receiver A (port 9) — multicast packets arrive at line rate.

  • Receiver B (port 8) — counter /sys/class/net/eth_blue/statistics/multicast stays flat (snooping confines the stream).

  • When Receiver A leaves (Ctrl-C on mcjoin or its -W timeout), the group ages out at last-member-query-interval x robustness-variable and the IPMC entry is removed; subsequent traffic to the group is dropped.