lkml.org 
[lkml]   [2017]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 194/199] mld: do not remove mld souce list info when set link down
    3.2.87-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Hangbin Liu <liuhangbin@gmail.com>

    commit 1666d49e1d416fcc2cce708242a52fe3317ea8ba upstream.

    This is an IPv6 version of commit 24803f38a5c0 ("igmp: do not remove igmp
    souce list..."). In mld_del_delrec(), we will restore back all source filter
    info instead of flush them.

    Move mld_clear_delrec() from ipv6_mc_down() to ipv6_mc_destroy_dev() since
    we should not remove source list info when set link down. Remove
    igmp6_group_dropped() in ipv6_mc_destroy_dev() since we have called it in
    ipv6_mc_down().

    Also clear all source info after igmp6_group_dropped() instead of in it
    because ipv6_mc_down() will call igmp6_group_dropped().

    Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    [bwh: Backported to 3.2:
    - Timer code moved around in ipv6_mc_down() is different
    - Adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    net/ipv6/mcast.c | 51 ++++++++++++++++++++++++++++++---------------------
    1 file changed, 30 insertions(+), 21 deletions(-)

    --- a/net/ipv6/mcast.c
    +++ b/net/ipv6/mcast.c
    @@ -92,7 +92,7 @@ static void mld_gq_timer_expire(unsigned
    static void mld_ifc_timer_expire(unsigned long data);
    static void mld_ifc_event(struct inet6_dev *idev);
    static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
    -static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr);
    +static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
    static void mld_clear_delrec(struct inet6_dev *idev);
    static int sf_setstate(struct ifmcaddr6 *pmc);
    static void sf_markstate(struct ifmcaddr6 *pmc);
    @@ -691,9 +691,9 @@ static void igmp6_group_dropped(struct i
    dev_mc_del(dev, buf);
    }

    - if (mc->mca_flags & MAF_NOREPORT)
    - goto done;
    spin_unlock_bh(&mc->mca_lock);
    + if (mc->mca_flags & MAF_NOREPORT)
    + return;

    if (!mc->idev->dead)
    igmp6_leave_group(mc);
    @@ -701,8 +701,6 @@ static void igmp6_group_dropped(struct i
    spin_lock_bh(&mc->mca_lock);
    if (del_timer(&mc->mca_timer))
    atomic_dec(&mc->mca_refcnt);
    -done:
    - ip6_mc_clear_src(mc);
    spin_unlock_bh(&mc->mca_lock);
    }

    @@ -747,10 +745,11 @@ static void mld_add_delrec(struct inet6_
    spin_unlock_bh(&idev->mc_lock);
    }

    -static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
    +static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
    {
    struct ifmcaddr6 *pmc, *pmc_prev;
    - struct ip6_sf_list *psf, *psf_next;
    + struct ip6_sf_list *psf;
    + struct in6_addr *pmca = &im->mca_addr;

    spin_lock_bh(&idev->mc_lock);
    pmc_prev = NULL;
    @@ -767,14 +766,20 @@ static void mld_del_delrec(struct inet6_
    }
    spin_unlock_bh(&idev->mc_lock);

    + spin_lock_bh(&im->mca_lock);
    if (pmc) {
    - for (psf=pmc->mca_tomb; psf; psf=psf_next) {
    - psf_next = psf->sf_next;
    - kfree(psf);
    + im->idev = pmc->idev;
    + im->mca_crcount = idev->mc_qrv;
    + im->mca_sfmode = pmc->mca_sfmode;
    + if (pmc->mca_sfmode == MCAST_INCLUDE) {
    + im->mca_tomb = pmc->mca_tomb;
    + im->mca_sources = pmc->mca_sources;
    + for (psf = im->mca_sources; psf; psf = psf->sf_next)
    + psf->sf_crcount = im->mca_crcount;
    }
    in6_dev_put(pmc->idev);
    - kfree(pmc);
    }
    + spin_unlock_bh(&im->mca_lock);
    }

    static void mld_clear_delrec(struct inet6_dev *idev)
    @@ -877,7 +882,7 @@ int ipv6_dev_mc_inc(struct net_device *d
    idev->mc_list = mc;
    write_unlock_bh(&idev->lock);

    - mld_del_delrec(idev, &mc->mca_addr);
    + mld_del_delrec(idev, mc);
    igmp6_group_added(mc);
    ma_put(mc);
    return 0;
    @@ -898,6 +903,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *
    write_unlock_bh(&idev->lock);

    igmp6_group_dropped(ma);
    + ip6_mc_clear_src(ma);

    ma_put(ma);
    return 0;
    @@ -2231,18 +2237,20 @@ void ipv6_mc_down(struct inet6_dev *idev
    /* Withdraw multicast list */

    read_lock_bh(&idev->lock);
    +
    + for (i = idev->mc_list; i; i=i->next)
    + igmp6_group_dropped(i);
    +
    + /* Should stop timer after group drop. or we will
    + * start timer again in mld_ifc_event()
    + */
    idev->mc_ifc_count = 0;
    if (del_timer(&idev->mc_ifc_timer))
    __in6_dev_put(idev);
    idev->mc_gq_running = 0;
    if (del_timer(&idev->mc_gq_timer))
    __in6_dev_put(idev);
    -
    - for (i = idev->mc_list; i; i=i->next)
    - igmp6_group_dropped(i);
    read_unlock_bh(&idev->lock);
    -
    - mld_clear_delrec(idev);
    }


    @@ -2255,8 +2263,10 @@ void ipv6_mc_up(struct inet6_dev *idev)
    /* Install multicast list, except for all-nodes (already installed) */

    read_lock_bh(&idev->lock);
    - for (i = idev->mc_list; i; i=i->next)
    + for (i = idev->mc_list; i; i = i->next) {
    + mld_del_delrec(idev, i);
    igmp6_group_added(i);
    + }
    read_unlock_bh(&idev->lock);
    }

    @@ -2289,6 +2299,7 @@ void ipv6_mc_destroy_dev(struct inet6_de

    /* Deactivate timers */
    ipv6_mc_down(idev);
    + mld_clear_delrec(idev);

    /* Delete all-nodes address. */
    /* We cannot call ipv6_dev_mc_dec() directly, our caller in
    @@ -2303,11 +2314,9 @@ void ipv6_mc_destroy_dev(struct inet6_de
    write_lock_bh(&idev->lock);
    while ((i = idev->mc_list) != NULL) {
    idev->mc_list = i->next;
    - write_unlock_bh(&idev->lock);

    - igmp6_group_dropped(i);
    + write_unlock_bh(&idev->lock);
    ma_put(i);
    -
    write_lock_bh(&idev->lock);
    }
    write_unlock_bh(&idev->lock);
    \
     
     \ /
      Last update: 2017-03-10 13:22    [W:4.143 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site