From patchwork Sat May 1 14:16:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oren Laadan X-Patchwork-Id: 51449 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 822A6B7D59 for ; Sun, 2 May 2010 00:43:45 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933254Ab0EAOmM (ORCPT ); Sat, 1 May 2010 10:42:12 -0400 Received: from tarap.cc.columbia.edu ([128.59.29.7]:64437 "EHLO tarap.cc.columbia.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932947Ab0EAOix (ORCPT ); Sat, 1 May 2010 10:38:53 -0400 Received: from localhost.localdomain (cpe-66-108-42-212.nyc.res.rr.com [66.108.42.212]) (user=ol2104 mech=PLAIN bits=0) by tarap.cc.columbia.edu (8.14.3/8.14.3) with ESMTP id o41EGSAJ028326 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Sat, 1 May 2010 10:38:28 -0400 (EDT) From: Oren Laadan To: Andrew Morton Cc: containers@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Serge Hallyn , Matt Helsley , Pavel Emelyanov , Dan Smith , netdev@vger.kernel.org Subject: [PATCH v21 095/100] c/r: Add rtnl_dellink() helper Date: Sat, 1 May 2010 10:16:17 -0400 Message-Id: <1272723382-19470-96-git-send-email-orenl@cs.columbia.edu> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1272723382-19470-1-git-send-email-orenl@cs.columbia.edu> References: <1272723382-19470-1-git-send-email-orenl@cs.columbia.edu> X-No-Spam-Score: Local X-Scanned-By: MIMEDefang 2.68 on 128.59.29.7 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dan Smith This is the kernel equivalent of "ip link del $name" and matches the existing rtnl_newlink() equivalent of "ip link add $name". It factors out the message creation and dispatch code a little further into rtnl_do() before adding the new function. Cc: netdev@vger.kernel.org Signed-off-by: Dan Smith --- net/checkpoint_dev.c | 86 +++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 72 insertions(+), 14 deletions(-) diff --git a/net/checkpoint_dev.c b/net/checkpoint_dev.c index 34a6bdb..5097011 100644 --- a/net/checkpoint_dev.c +++ b/net/checkpoint_dev.c @@ -475,22 +475,49 @@ static struct sk_buff *new_link_msg(new_link_fn fn, void *data, char *name) return skb; } -static struct net_device *rtnl_newlink(new_link_fn fn, void *data, char *name) +static struct sk_buff *del_link_msg(char *name) +{ + int ret = -ENOMEM; + int flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK; + struct nlmsghdr *nlh; + struct sk_buff *skb; + struct ifinfomsg *ifm; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return ERR_PTR(-ENOMEM); + + nlh = nlmsg_put(skb, 0, 0, RTM_DELLINK, sizeof(*ifm), flags); + if (!nlh) + goto out; + + ifm = nlmsg_data(nlh); + memset(ifm, 0, sizeof(*ifm)); + + ret = nla_put_string(skb, IFLA_IFNAME, name); + if (ret) + goto out; + + nlmsg_end(skb, nlh); + + out: + if (ret < 0) { + kfree_skb(skb); + skb = ERR_PTR(ret); + } + + return skb; +} + +static int rtnl_do(struct sk_buff *skb) { int ret = -ENOMEM; struct socket *rtnl = NULL; - struct sk_buff *skb = NULL; + struct sk_buff *rskb = NULL; struct nlmsghdr *nlh; struct msghdr msg; struct kvec kvec; - skb = new_link_msg(fn, data, name); - if (IS_ERR(skb)) { - ckpt_debug("failed to create new link message: %li\n", - PTR_ERR(skb)); - return ERR_PTR(PTR_ERR(skb)); - } - memset(&msg, 0, sizeof(msg)); kvec.iov_len = skb->len; kvec.iov_base = skb->head; @@ -510,25 +537,56 @@ static struct net_device *rtnl_newlink(new_link_fn fn, void *data, char *name) goto out; } - /* Free the send skb to make room for the receive skb */ - kfree_skb(skb); - - nlh = rtnl_get_response(rtnl, &skb); + nlh = rtnl_get_response(rtnl, &rskb); if (IS_ERR(nlh)) { ret = PTR_ERR(nlh); ckpt_debug("RTNETLINK said: %i\n", ret); } out: rtnl_close(rtnl); + kfree_skb(rskb); out_noclose: - kfree_skb(skb); + return ret; +} +static struct net_device *rtnl_newlink(new_link_fn fn, void *data, char *name) +{ + struct sk_buff *skb; + int ret; + + skb = new_link_msg(fn, data, name); + if (IS_ERR(skb)) { + ckpt_debug("failed to create new link message: %li\n", + PTR_ERR(skb)); + return ERR_PTR(PTR_ERR(skb)); + } + + ret = rtnl_do(skb); + kfree_skb(skb); if (ret < 0) return ERR_PTR(ret); else return dev_get_by_name(current->nsproxy->net_ns, name); } +static int rtnl_dellink(char *name) +{ + struct sk_buff *skb; + int ret; + + skb = del_link_msg(name); + if (IS_ERR(skb)) { + ckpt_debug("failed to create del link message: %li\n", + PTR_ERR(skb)); + return PTR_ERR(skb); + } + + ret = rtnl_do(skb); + kfree_skb(skb); + + return ret; +} + static int netdev_noop(void *data) { return 0;