From patchwork Fri Jun 28 16:13:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 255458 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 201E82C0084 for ; Sat, 29 Jun 2013 02:14:00 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755544Ab3F1QNo (ORCPT ); Fri, 28 Jun 2013 12:13:44 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:52426 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753964Ab3F1QNn (ORCPT ); Fri, 28 Jun 2013 12:13:43 -0400 Received: by mail-pa0-f41.google.com with SMTP id bj3so2645182pad.28 for ; Fri, 28 Jun 2013 09:13:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:from:to:cc:subject:message-id:in-reply-to:references:x-mailer :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=xqdXEmj2kdKCTesmqh9pqtsONPxCryV9H5YmsZOOiNA=; b=oDYAfYaalVtE9gxV2ET0K6be9a7cPsHYCBIb5ek80OIY3n7tQC3jCFOlbdbp9KEIQ7 O0yZxKMQ35vr6uDnZu6LNVaqk75HSTvWGG2re5bSrxM4debOGZfzX3DOZy4M8B4iGPn/ CoZ653BIg2uyGVtlX670NB2NA033U1ysGhRaaiO6qP6sfXlz1kPW5ZXD7R9IV39AkIV+ MBLGXrd85tlIn8mCFcEYrnUHPHuhR1s7a70G9TPd/t7Hu/3XfAkv+Gf53JfTN4PQztWr DfuWU6766Y7Ob+P9fsLPP28hV8GF+NcgyUCkPkU+h+OZyPuho8CbHuOJfdQad2ikFZYa sKQA== X-Received: by 10.68.108.163 with SMTP id hl3mr12195467pbb.160.1372436022402; Fri, 28 Jun 2013 09:13:42 -0700 (PDT) Received: from nehalam.linuxnetplumber.net (static-50-53-71-109.bvtn.or.frontiernet.net. [50.53.71.109]) by mx.google.com with ESMTPSA id jf4sm8779673pbb.19.2013.06.28.09.13.41 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 28 Jun 2013 09:13:41 -0700 (PDT) Date: Fri, 28 Jun 2013 09:13:38 -0700 From: Stephen Hemminger To: nicolas.dichtel@6wind.com Cc: Sven-Thorsten Dietrich , LKML , Stephen Hemminger , "netdev@vger.kernel.org" , Mike Davison Subject: [RFC net] netconf: set mulitcast family for multicast forwarding messages Message-ID: <20130628091338.547bd88d@nehalam.linuxnetplumber.net> In-Reply-To: <51CDB1AD.1020202@6wind.com> References: <1372376687.21767.10.camel@imac-linux.luckyscavenger.com> <20130628082617.42a802a4@nehalam.linuxnetplumber.net> <51CDB1AD.1020202@6wind.com> X-Mailer: Claws Mail 3.8.1 (GTK+ 2.24.10; x86_64-pc-linux-gnu) Mime-Version: 1.0 X-Gm-Message-State: ALoCoQlVi5VMBeSvMPo/b0wJoLvB9umhPjwclEvu5qEUEZFPA10cwgMAqaicpRPVRxI3A2Qrn2GU Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Revised version of Sven's patch. The idea is that multicast forwarding should be under the multicast address family like other multicast netlink messages. This version generates each family under separate headers when doing dump all. Compile tested only, this is to show some of the issues that need to be covered. Signed-off-by: Stephen Hemminger --- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/net/ipv4/devinet.c 2013-06-11 09:50:21.550918636 -0700 +++ b/net/ipv4/devinet.c 2013-06-28 09:07:18.147829543 -0700 @@ -1685,6 +1685,11 @@ static int inet_netconf_msgsize_devconf( size += nla_total_size(4); if (type == -1 || type == NETCONFA_RP_FILTER) size += nla_total_size(4); + + /* additional header for MC family */ + if (type == -1) + size += NLMSG_ALIGN(sizeof(struct netconfmsg)) + + nla_total_size(4); if (type == -1 || type == NETCONFA_MC_FORWARDING) size += nla_total_size(4); @@ -1694,7 +1699,7 @@ static int inet_netconf_msgsize_devconf( static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex, struct ipv4_devconf *devconf, u32 portid, u32 seq, int event, unsigned int flags, - int type) + u8 family, int type) { struct nlmsghdr *nlh; struct netconfmsg *ncm; @@ -1705,21 +1710,24 @@ static int inet_netconf_fill_devconf(str return -EMSGSIZE; ncm = nlmsg_data(nlh); - ncm->ncm_family = AF_INET; + ncm->ncm_family = family; if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0) goto nla_put_failure; /* type -1 is used for ALL */ - if ((type == -1 || type == NETCONFA_FORWARDING) && + if (((type == -1 && family == AF_INET) || + type == NETCONFA_FORWARDING) && nla_put_s32(skb, NETCONFA_FORWARDING, IPV4_DEVCONF(*devconf, FORWARDING)) < 0) goto nla_put_failure; - if ((type == -1 || type == NETCONFA_RP_FILTER) && + if (((type == -1 && family == AF_INET) || + type == NETCONFA_RP_FILTER) && nla_put_s32(skb, NETCONFA_RP_FILTER, IPV4_DEVCONF(*devconf, RP_FILTER)) < 0) goto nla_put_failure; - if ((type == -1 || type == NETCONFA_MC_FORWARDING) && + if (((type == -1 || family == RTNL_FAMILY_IPMR) || + type == NETCONFA_MC_FORWARDING) && nla_put_s32(skb, NETCONFA_MC_FORWARDING, IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0) goto nla_put_failure; @@ -1737,12 +1745,17 @@ void inet_netconf_notify_devconf(struct struct sk_buff *skb; int err = -ENOBUFS; + BUG_ON(type == -1); /* ALL is not valid for notification */ + skb = nlmsg_new(inet_netconf_msgsize_devconf(type), GFP_ATOMIC); if (skb == NULL) goto errout; err = inet_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, - RTM_NEWNETCONF, 0, type); + RTM_NEWNETCONF, 0, + (type == NETCONFA_MC_FORWARDING) ? + RTNL_FAMILY_IPMR : AF_INET, + type); if (err < 0) { /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */ WARN_ON(err == -EMSGSIZE); @@ -1811,13 +1824,23 @@ static int inet_netconf_get_devconf(stru err = inet_netconf_fill_devconf(skb, ifindex, devconf, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, RTM_NEWNETCONF, 0, - -1); + AF_INET, -1); if (err < 0) { /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */ WARN_ON(err == -EMSGSIZE); kfree_skb(skb); goto errout; } + + err = inet_netconf_fill_devconf(skb, ifindex, devconf, + NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, RTM_NEWNETCONF, 0, + RTNL_FAMILY_IPMR, -1); + if (err < 0) { + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); errout: return err; @@ -1855,10 +1878,23 @@ static int inet_netconf_dump_devconf(str cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, + AF_INET, + -1) <= 0) { + rcu_read_unlock(); + goto done; + } + if (inet_netconf_fill_devconf(skb, dev->ifindex, + &in_dev->cnf, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, + NLM_F_MULTI, + RTNL_FAMILY_IPMR, -1) <= 0) { rcu_read_unlock(); goto done; } + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); cont: idx++; @@ -1871,10 +1907,18 @@ cont: NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, - -1) <= 0) + AF_INET, -1) <= 0) + goto done; + + if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL, + net->ipv4.devconf_all, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, NLM_F_MULTI, + RTNL_FAMILY_IPMR, -1) <= 0) goto done; - else - h++; + + h++; } if (h == NETDEV_HASHENTRIES + 1) { if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, @@ -1882,10 +1926,18 @@ cont: NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, - -1) <= 0) + AF_INET, -1) <= 0) goto done; - else - h++; + + if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, + net->ipv4.devconf_dflt, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, NLM_F_MULTI, + RTNL_FAMILY_IPMR, -1) <= 0) + goto done; + + h++; } done: cb->args[0] = h; --- a/net/ipv6/addrconf.c 2013-06-28 08:17:16.424664740 -0700 +++ b/net/ipv6/addrconf.c 2013-06-28 09:10:32.336959806 -0700 @@ -471,6 +471,9 @@ static int inet6_netconf_msgsize_devconf if (type == -1 || type == NETCONFA_FORWARDING) size += nla_total_size(4); #ifdef CONFIG_IPV6_MROUTE + if (type == -1) + size += NLMSG_ALIGN(sizeof(struct netconfmsg)) + + nla_total_size(4); if (type == -1 || type == NETCONFA_MC_FORWARDING) size += nla_total_size(4); #endif @@ -481,7 +484,7 @@ static int inet6_netconf_msgsize_devconf static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, struct ipv6_devconf *devconf, u32 portid, u32 seq, int event, unsigned int flags, - int type) + u8 family, int type) { struct nlmsghdr *nlh; struct netconfmsg *ncm; @@ -492,17 +495,19 @@ static int inet6_netconf_fill_devconf(st return -EMSGSIZE; ncm = nlmsg_data(nlh); - ncm->ncm_family = AF_INET6; + ncm->ncm_family = family; if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0) goto nla_put_failure; /* type -1 is used for ALL */ - if ((type == -1 || type == NETCONFA_FORWARDING) && + if (((type == -1 && family == AF_INET6) || + type == NETCONFA_FORWARDING) && nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0) goto nla_put_failure; #ifdef CONFIG_IPV6_MROUTE - if ((type == -1 || type == NETCONFA_MC_FORWARDING) && + if (((type == -1 && family == RTNL_FAMILY_IP6MR) || + type == NETCONFA_MC_FORWARDING) && nla_put_s32(skb, NETCONFA_MC_FORWARDING, devconf->mc_forwarding) < 0) goto nla_put_failure; @@ -520,12 +525,23 @@ void inet6_netconf_notify_devconf(struct struct sk_buff *skb; int err = -ENOBUFS; + BUG_ON(type == -1); + skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC); if (skb == NULL) goto errout; +#ifdef CONFIG_IPV6_MROUTE + if (type == NETCONFA_MC_FORWARDING) + err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, + RTM_NEWNETCONF, 0, + RTNL_FAMILY_IP6MR, type); + else +#endif err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, - RTM_NEWNETCONF, 0, type); + RTM_NEWNETCONF, 0, + AF_INET6, type); +#endif if (err < 0) { /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ WARN_ON(err == -EMSGSIZE); @@ -592,13 +608,25 @@ static int inet6_netconf_get_devconf(str err = inet6_netconf_fill_devconf(skb, ifindex, devconf, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, RTM_NEWNETCONF, 0, - -1); + AF_INET6, -1); + if (err < 0) { + /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } +#ifdef CONFIG_IPV6_MROUTE + err = inet6_netconf_fill_devconf(skb, ifindex, devconf, + NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, RTM_NEWNETCONF, 0, + RTNL_FAMILY_IP6MR, -1); if (err < 0) { /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ WARN_ON(err == -EMSGSIZE); kfree_skb(skb); goto errout; } +#endif err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); errout: return err; @@ -636,10 +664,23 @@ static int inet6_netconf_dump_devconf(st cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, + AF_INET6, -1) <= 0) { + rcu_read_unlock(); + goto done; + } +#ifdef CONFIG_IPV6_MROUTE + if (inet6_netconf_fill_devconf(skb, dev->ifindex, + &idev->cnf, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, + NLM_F_MULTI, + RTNL_FAMILY_IP6MR, -1) <= 0) { rcu_read_unlock(); goto done; } +#endif nl_dump_check_consistent(cb, nlmsg_hdr(skb)); cont: idx++; @@ -652,10 +693,18 @@ cont: NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, - -1) <= 0) + AF_INET6, -1) <= 0) goto done; - else - h++; +#ifdef CONFIG_IPV6_MROUTE + if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL, + net->ipv6.devconf_all, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, NLM_F_MULTI, + RTNL_FAMILY_IP6MR, -1) <= 0) + goto done; +#endif + h++; } if (h == NETDEV_HASHENTRIES + 1) { if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, @@ -663,9 +712,17 @@ cont: NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, RTM_NEWNETCONF, NLM_F_MULTI, - -1) <= 0) + AF_INET6, -1) <= 0) + goto done; +#ifdef CONFIG_IPV6_MROUTE + if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, + net->ipv6.devconf_dflt, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNETCONF, NLM_F_MULTI, + RTNL_FAMILY_IP6MR, -1) <= 0) goto done; - else +#endif h++; } done: