From patchwork Wed Jul 2 05:50:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ding Tianhong X-Patchwork-Id: 32942 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ig0-f199.google.com (mail-ig0-f199.google.com [209.85.213.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1D80D20672 for ; Wed, 2 Jul 2014 05:51:12 +0000 (UTC) Received: by mail-ig0-f199.google.com with SMTP id h18sf24897967igc.6 for ; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:message-id:date:from:user-agent :mime-version:to:subject:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=EW84i8Yfhj1FCMEXO2CjdcFln+xoR10Z6kAJPo5wwdU=; b=BfjDL7nxUF+qMRf7QUgVIV5yLmoBoilVSHNec5xNxTQGLAMaB+bEUEsf5c8e07GVce XyuJ6vhZYcPnBMjklWy5ieJIW7RAFYqdQvpk3Ws9YUTrCcLPHjieG/ajbjCIQsfnx8Cj ZdJRP/vpvy1dtsRjLMFVlUSjdt5lr92XS42vbKVvCxDFsl3RriHqkstxdmQ7/J6MhtY4 wGYV/RgXh2mFW6f6dEm0iyZwrHVbC9h0zeEH/vhR3La3NW4nucKp5U/QbdoTngeVq8WU nWEjAyOqADYnxuldOegtZx4Yv27GoCWxoU5iaDQ8ErG7NQIoe1Y9kXx15mGXln8PkPQW +fPA== X-Gm-Message-State: ALoCoQm0cuNiaKNBca7XF/xADbJ2hLYLViny2eUeH6V/ro/kjAhwupddVLPLjH4nTUJ5knQNUtQe X-Received: by 10.182.213.135 with SMTP id ns7mr25996056obc.46.1404280271606; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.95.247 with SMTP id i110ls2024105qge.20.gmail; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) X-Received: by 10.52.189.161 with SMTP id gj1mr39911852vdc.2.1404280271516; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id hk8si12423656vdb.79.2014.07.01.22.51.11 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 01 Jul 2014 22:51:11 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id id10so9927187vcb.38 for ; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) X-Received: by 10.220.69.72 with SMTP id y8mr47784576vci.21.1404280271436; Tue, 01 Jul 2014 22:51:11 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp268646vcb; Tue, 1 Jul 2014 22:51:11 -0700 (PDT) X-Received: by 10.68.180.65 with SMTP id dm1mr67268921pbc.142.1404280270684; Tue, 01 Jul 2014 22:51:10 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bm3si29232713pbc.86.2014.07.01.22.51.10; Tue, 01 Jul 2014 22:51:10 -0700 (PDT) Received-SPF: none (google.com: netdev-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752487AbaGBFvG (ORCPT + 3 others); Wed, 2 Jul 2014 01:51:06 -0400 Received: from szxga01-in.huawei.com ([119.145.14.64]:40474 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751797AbaGBFvF (ORCPT ); Wed, 2 Jul 2014 01:51:05 -0400 Received: from 172.24.2.119 (EHLO szxeml412-hub.china.huawei.com) ([172.24.2.119]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id BYA68941; Wed, 02 Jul 2014 13:50:56 +0800 (CST) Received: from [127.0.0.1] (10.177.22.246) by szxeml412-hub.china.huawei.com (10.82.67.91) with Microsoft SMTP Server id 14.3.158.1; Wed, 2 Jul 2014 13:50:51 +0800 Message-ID: <53B39DB8.2060306@huawei.com> Date: Wed, 2 Jul 2014 13:50:48 +0800 From: Ding Tianhong User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.0.1 MIME-Version: 1.0 To: "David S. Miller" , Alexey Kuznetsov , James Morris , Hideaki YOSHIFUJI , Patrick McHardy , Netdev Subject: [PATCH net v2] igmp: fix the problem when mc leave group X-Originating-IP: [10.177.22.246] X-CFilter-Loop: Reflected Sender: netdev-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: netdev@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: dingtianhong@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The problem was triggered by these steps: 1) create socket, bind and then setsockopt for add mc group. mreq.imr_multiaddr.s_addr = inet_addr("255.0.0.37"); mreq.imr_interface.s_addr = inet_addr("192.168.1.2"); setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); 2) drop the mc group for this socket. mreq.imr_multiaddr.s_addr = inet_addr("255.0.0.37"); mreq.imr_interface.s_addr = inet_addr("0.0.0.0"); setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); 3) and then drop the socket, I found the mc group was still used by the dev: netstat -g Interface RefCnt Group --------------- ------ --------------------- eth2 1 255.0.0.37 Normally even though the IP_DROP_MEMBERSHIP return error, the mc group still need to be released for the netdev when drop the socket, but this process was broken when route default is NULL, the reason is that: The ip_mc_leave_group() will choose the in_dev by the imr_interface.s_addr, if input addr is NULL, the default route dev will be chosen, then the ifindex is got from the dev, then polling the inet->mc_list and return -ENODEV, but if the default route dev is NULL, the in_dev and ifIndex is both NULL, when polling the inet->mc_list, the mc group will be released from the mc_list, but the dev didn't dec the refcnt for this mc group, so when dropping the socket, the mc_list is NULL and the dev still keep this group. v1->v2: According Hideaki's suggestion, we should align with IPv6 (RFC3493) and BSDs, so I add the checking for the in_dev before polling the mc_list, make sure when we remove the mc group, dec the refcnt to the real dev which was using the mc address. The problem would never happened again. Signed-off-by: Ding Tianhong --- net/ipv4/igmp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 17d34e3..7fb6565 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1944,6 +1944,10 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) rtnl_lock(); in_dev = ip_mc_find_dev(net, imr); + if (!in_dev) { + ret = -ENODEV; + goto out; + } ifindex = imr->imr_ifindex; for (imlp = &inet->mc_list; (iml = rtnl_dereference(*imlp)) != NULL; @@ -1961,16 +1965,14 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) *imlp = iml->next_rcu; - if (in_dev) - ip_mc_dec_group(in_dev, group); + ip_mc_dec_group(in_dev, group); rtnl_unlock(); /* decrease mem now to avoid the memleak warning */ atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); kfree_rcu(iml, rcu); return 0; } - if (!in_dev) - ret = -ENODEV; +out: rtnl_unlock(); return ret; }