• Hangbin Liu's avatar
    ipv4/igmp: init group mode as INCLUDE when join source group · 6e2059b5
    Hangbin Liu authored
    Based on RFC3376 5.1
       If no interface
       state existed for that multicast address before the change (i.e., the
       change consisted of creating a new per-interface record), or if no
       state exists after the change (i.e., the change consisted of deleting
       a per-interface record), then the "non-existent" state is considered
       to have a filter mode of INCLUDE and an empty source list.
    
    Which means a new multicast group should start with state IN().
    
    Function ip_mc_join_group() works correctly for IGMP ASM(Any-Source Multicast)
    mode. It adds a group with state EX() and inits crcount to mc_qrv,
    so the kernel will send a TO_EX() report message after adding group.
    
    But for IGMPv3 SSM(Source-specific multicast) JOIN_SOURCE_GROUP mode, we
    split the group joining into two steps. First we join the group like ASM,
    i.e. via ip_mc_join_group(). So the state changes from IN() to EX().
    
    Then we add the source-specific address with INCLUDE mode. So the state
    changes from EX() to IN(A).
    
    Before the first step sends a group change record, we finished the second
    step. So we will only send the second change record. i.e. TO_IN(A).
    
    Regarding the RFC stands, we should actually send an ALLOW(A) message for
    SSM JOIN_SOURCE_GROUP as the state should mimic the 'IN() to IN(A)'
    transition.
    
    The issue was exposed by commit a052517a ("net/multicast: should not
    send source list records when have filter mode change"). Before this change,
    we used to send both ALLOW(A) and TO_IN(A). After this change we only send
    TO_IN(A).
    
    Fix it by adding a new parameter to init group mode. Also add new wrapper
    functions so we don't need to change too much code.
    
    v1 -> v2:
    In my first version I only cleared the group change record. But this is not
    enough. Because when a new group join, it will init as EXCLUDE and trigger
    an filter mode change in ip/ip6_mc_add_src(), which will clear all source
    addresses' sf_crcount. This will prevent early joined address sending state
    change records if multi source addressed joined at the same time.
    
    In v2 patch, I fixed it by directly initializing the mode to INCLUDE for SSM
    JOIN_SOURCE_GROUP. I also split the original patch into two separated patches
    for IPv4 and IPv6.
    
    Fixes: a052517a ("net/multicast: should not send source list records when have filter mode change")
    Reviewed-by: default avatarStefano Brivio <sbrivio@redhat.com>
    Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    6e2059b5
igmp.c 73 KB