From patchwork Sun Nov 10 08:19:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yuyang Huang X-Patchwork-Id: 13869777 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DB08233D62 for ; Sun, 10 Nov 2024 08:20:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731226831; cv=none; b=BeLk/np1rWvEIP7xEwV4tAZBZWzWhWsIE1/XcImJfWY/Gi3ZOlqNWqoJ8ZUgWSGaQ2lToKgWVceDXVQr2pBs4zFhYg8sJEw3MStWzlmLwpWG56TZeZzjN2Lduu3+XcguAalHT1RvWU5aTs6v6tUKPOlI5r+PuKIQeH215naDq40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731226831; c=relaxed/simple; bh=Gl1eG3hRAbBuZVpFh0gg6rz9L8Cy6YPpES9UkmeFlZM=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=ryb52i3sRiKL5woyKcfiwpt/fns71FrTyaxh27IL++IUd1pVc4KTOjZm7qPSjqRfo6biHROdHZgmKXc8EUBEA4PebWKzY9V2vyKtPut0Gjnq5sNMY/BO+6u1Ybpm902RBDAclPcfcvTDUYkfCbSYACry9x+Dyy5Sw5x52KVJ+gs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--yuyanghuang.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=EojmDOEt; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--yuyanghuang.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EojmDOEt" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6ea863ecfe9so70998537b3.3 for ; Sun, 10 Nov 2024 00:20:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1731226829; x=1731831629; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:from:to:cc:subject:date:message-id:reply-to; bh=fB+41F93YGE8eZYLka5AvuVAKCJamBaTPqGwxxikWbY=; b=EojmDOEt2qWDCp41G554BbeFYLjZXuJusdaEcjREMnUfgtwk5lbW9xpWJ68XrxAsm5 Ck6GESphBcJuKlyiOzsl9fTKv97irraAljR72PTNblxKdL3lpImaSHAVpjn/1WpoShtW rUUlvWcLs5g0RDFV9NcHsPBIutrZJQIEuZlzzIB3F3/FP6pQK3xOJACmzQRloy4J8G3v wux2Wqw5BnkwagUJ/Ub2WqcbjBB0HVqRyZft6GhWiuCUN2CxckWX97QnPLjXT9vWI8JZ dLtfE6evm8l9z217uTHWoalkLeDJFJmoefZ7QENU+4PYQ1YEeLuM+6LCzTK/KzytT8LD 3rEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731226829; x=1731831629; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fB+41F93YGE8eZYLka5AvuVAKCJamBaTPqGwxxikWbY=; b=v3x6EuZcA4ZakhNdKnpkzkrrn8sZRLP1aLAH4C4jn/e01/awBSrbA3UiC85hwHyIKJ /vvtlClts7TRSxfE3ZHggss4jQvGUPoqqlbbf5bepYG2EnbbRnzPJDAJafnX1WRLAC6A khAanv8ZFD78NdSwAzuJ4DggWreJFpCaLSMphMq4RytCU9u/ltbq/qef1XZjz9Ye7zqh WtReFahSEx0qv0Qf2FsdlEjeOnxkRkLvXtyDoWKKEKgCZxvKYMjYhyuW6myPASyzJ84A QB2g3iGHf3rF2D0BBmDzlrGTEg6AO2WExaJhQ5phrmNcPI8fMkRqzodzUSlWmDzAbSfq mdzg== X-Forwarded-Encrypted: i=1; AJvYcCXA0o5NgYvKRB9Ex4YCZS7rmz6XqnMw2PvXzGqfwjxmpdRtni39jNUBCwaJ1JThWjNBmsiawaE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3Zn0Poa0fZGFZNZZl8N9SgfNGvwIIAE2ylrmi1WlERykaMkcU WzwPqnmWuBwTuj/I7f6/7b+LrSGT0hup1IX1EPWCPhvCw8I5DR3ykVnI8/SXyubzA17tTUoa0C1 OKtH4NNc9y+tiewmwmDX0Sw== X-Google-Smtp-Source: AGHT+IHoDWALQV8yPFMYbn5Kn8mnbl/DOuouYIGB+XoHYcDgC62Wz2mRtoF+4cutEKttcTbdojFvTieyI0jpuEE7eA== X-Received: from yuyanghuang.tok.corp.google.com ([2401:fa00:8f:203:9315:4df6:5ed3:1684]) (user=yuyanghuang job=sendgmr) by 2002:a0d:e703:0:b0:64a:e220:bfb5 with SMTP id 00721157ae682-6eaddd87123mr500877b3.1.1731226828788; Sun, 10 Nov 2024 00:20:28 -0800 (PST) Date: Sun, 10 Nov 2024 17:19:53 +0900 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.47.0.277.g8800431eea-goog Message-ID: <20241110081953.121682-1-yuyanghuang@google.com> Subject: [PATCH net-next] netlink: add igmp join/leave notifications From: Yuyang Huang To: Yuyang Huang Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , David Ahern , roopa@cumulusnetworks.com, jiri@resnulli.us, stephen@networkplumber.org, netdev@vger.kernel.org, " =?utf-8?q?Maciej_=C5=BBenczykowski?= " , Lorenzo Colitti , Patrick Ruddy X-Patchwork-Delegate: kuba@kernel.org This change introduces netlink notifications for multicast address changes, enabling components like the Android Packet Filter to implement IGMP offload solutions. The following features are included: * Addition and deletion of multicast addresses are reported using RTM_NEWMULTICAST and RTM_DELMULTICAST messages with AF_INET. * A new notification group, RTNLGRP_IPV4_MCADDR, is introduced for receiving these events. This enhancement allows user-space components to efficiently track multicast group memberships and program hardware offload filters accordingly. Cc: Maciej Żenczykowski Cc: Lorenzo Colitti Co-developed-by: Patrick Ruddy Signed-off-by: Patrick Ruddy Link: https://lore.kernel.org/r/20180906091056.21109-1-pruddy@vyatta.att-mail.com Signed-off-by: Yuyang Huang --- include/uapi/linux/rtnetlink.h | 6 ++++ net/ipv4/igmp.c | 58 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index 3b687d20c9ed..354a923f129d 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -93,6 +93,10 @@ enum { RTM_NEWPREFIX = 52, #define RTM_NEWPREFIX RTM_NEWPREFIX + RTM_NEWMULTICAST, +#define RTM_NEWMULTICAST RTM_NEWMULTICAST + RTM_DELMULTICAST, +#define RTM_DELMULTICAST RTM_DELMULTICAST RTM_GETMULTICAST = 58, #define RTM_GETMULTICAST RTM_GETMULTICAST @@ -774,6 +778,8 @@ enum rtnetlink_groups { #define RTNLGRP_TUNNEL RTNLGRP_TUNNEL RTNLGRP_STATS, #define RTNLGRP_STATS RTNLGRP_STATS + RTNLGRP_IPV4_MCADDR, +#define RTNLGRP_IPV4_MCADDR RTNLGRP_IPV4_MCADDR __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 9bf09de6a2e7..34575f5392a8 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -88,6 +88,7 @@ #include #include +#include #include #include #include @@ -1430,6 +1431,60 @@ static void ip_mc_hash_remove(struct in_device *in_dev, *mc_hash = im->next_hash; } +static int inet_fill_ifmcaddr(struct sk_buff *skb, struct net_device *dev, + __be32 addr, int event) +{ + struct nlmsghdr *nlh; + struct ifaddrmsg *ifm; + + nlh = nlmsg_put(skb, 0, 0, event, sizeof(struct ifaddrmsg), 0); + if (!nlh) + return -EMSGSIZE; + + ifm = nlmsg_data(nlh); + ifm->ifa_family = AF_INET; + ifm->ifa_prefixlen = 32; + ifm->ifa_flags = IFA_F_PERMANENT; + ifm->ifa_scope = RT_SCOPE_LINK; + ifm->ifa_index = dev->ifindex; + + if (nla_put_in_addr(skb, IFA_MULTICAST, addr) < 0) { + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; + } + + nlmsg_end(skb, nlh); + return 0; +} + +static inline int inet_ifmcaddr_msgsize(void) +{ + return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + nla_total_size(sizeof(__be32)); +} + +static void inet_ifmcaddr_notify(struct net_device *dev, __be32 addr, int event) +{ + struct net *net = dev_net(dev); + struct sk_buff *skb; + int err = -ENOBUFS; + + skb = nlmsg_new(inet_ifmcaddr_msgsize(), GFP_ATOMIC); + if (!skb) + goto error; + + err = inet_fill_ifmcaddr(skb, dev, addr, event); + if (err < 0) { + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto error; + } + + rtnl_notify(skb, net, 0, RTNLGRP_IPV4_MCADDR, NULL, GFP_ATOMIC); + return; +error: + rtnl_set_sk_err(net, RTNLGRP_IPV4_MCADDR, err); +} /* * A socket has joined a multicast group on device dev. @@ -1476,6 +1531,7 @@ static void ____ip_mc_inc_group(struct in_device *in_dev, __be32 addr, igmpv3_del_delrec(in_dev, im); #endif igmp_group_added(im); + inet_ifmcaddr_notify(in_dev->dev, addr, RTM_NEWMULTICAST); if (!in_dev->dead) ip_rt_multicast_event(in_dev); out: @@ -1689,6 +1745,8 @@ void __ip_mc_dec_group(struct in_device *in_dev, __be32 addr, gfp_t gfp) *ip = i->next_rcu; in_dev->mc_count--; __igmp_group_dropped(i, gfp); + inet_ifmcaddr_notify(in_dev->dev, addr, + RTM_DELMULTICAST); ip_mc_clear_src(i); if (!in_dev->dead)