From patchwork Wed Mar 28 01:21:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 891927 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="MVDXX2z1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 409qqs1Q6lz9rxx for ; Wed, 28 Mar 2018 12:22:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752856AbeC1BWM (ORCPT ); Tue, 27 Mar 2018 21:22:12 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:35181 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752839AbeC1BWK (ORCPT ); Tue, 27 Mar 2018 21:22:10 -0400 Received: by mail-pf0-f196.google.com with SMTP id u86so350203pfd.2 for ; Tue, 27 Mar 2018 18:22:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4+eXqC0bcNJ3oj6WgPWb5qNnMpipH6NdshbAy7kKkjM=; b=MVDXX2z1KS3uXOHZhZPzuPTVvnPR6RMD7pGsxVU+VJobUf+/FEXAzW5r6flQvg6+GC BeN2Frhhz60PEHSJRP9d426ME3rS3A/w9QvT8/2TxLVphLKe/zLME6N5X7xnSrM7oLxd jS3Aa+pWV48Ul7kEi3dLdDPWLiE86FYCkzcRk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4+eXqC0bcNJ3oj6WgPWb5qNnMpipH6NdshbAy7kKkjM=; b=m4+LYutKOqVMYG/CTab6TAbuCkQQojB0K9q7FX7zGGJPzueM3NA7IIN3Sn0f5vsWBQ zVAQIjTFsDOI2zG+kffuTd/gN4GuotSeULugyW/CRFbbUayvkHRyAdXt3Z0LaarE0KI5 Rqyvh4nqmhtKzaflxxhIRWdClPdEQyE2WKt7YLZbGFMzKpdB1w4h/aNWyt7iXWgvdz1c vh5FBPLWAKGKflW88tZttJAs7MIS6yByqoAYJTijefeColtkyYgdll11LYMoEm3BhIDE BszOoBBQFUHeS+EASo8OEtqZ4InLztwrKV89Zjye2EWcgeHK5xwvmw74ipPyNrS2QT7/ Kk4w== X-Gm-Message-State: AElRT7F+IR6tR1x/M8z5l8Yniee9QrxlUj9HfTyqpZMQRDn/m8IoZv9O qXsLx+Vm5Zu7smDiF8/Ce0X+NdH2 X-Google-Smtp-Source: AIpwx4/UwbDfpTEJA2AK158+A9TSzGEKUbb73QXwncCTZcIJLhzlvxhm1qUhkXYlUmADtJZR/fQiQA== X-Received: by 10.98.10.156 with SMTP id 28mr1245930pfk.33.1522200129324; Tue, 27 Mar 2018 18:22:09 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id y18sm4798595pfe.67.2018.03.27.18.22.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Mar 2018 18:22:08 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, roopa@cumulusnetworks.com, shm@cumulusnetworks.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, andy.roulin@gmail.com, David Ahern Subject: [PATCH net-next 2/6] net: Move call_fib_rule_notifiers up in fib_nl_newrule Date: Tue, 27 Mar 2018 18:21:56 -0700 Message-Id: <20180328012200.15175-3-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com> References: <20180328012200.15175-1-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Move call_fib_rule_notifiers up in fib_nl_newrule to the point right before the rule is inserted into the list. At this point there are no more failure paths within the core rule code, so if the notifier does not fail then the rule will be inserted into the list. Signed-off-by: David Ahern Reviewed-by: Ido Schimmel --- net/core/fib_rules.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 9d87ce868402..33958f84c173 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -631,6 +631,11 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, if (err < 0) goto errout_free; + err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, + extack); + if (err < 0) + goto errout_free; + list_for_each_entry(r, &ops->rules_list, list) { if (r->pref > rule->pref) break; @@ -667,7 +672,6 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, if (rule->tun_id) ip_tunnel_need_metadata(); - call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, extack); notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); flush_route_cache(ops); rules_ops_put(ops); From patchwork Wed Mar 28 01:21:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 891924 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="Gf89uwV0"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 409qqX6mxPz9s0x for ; Wed, 28 Mar 2018 12:22:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752859AbeC1BWO (ORCPT ); Tue, 27 Mar 2018 21:22:14 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:46565 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752594AbeC1BWL (ORCPT ); Tue, 27 Mar 2018 21:22:11 -0400 Received: by mail-pg0-f68.google.com with SMTP id t12so325222pgp.13 for ; Tue, 27 Mar 2018 18:22:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=54YsztpC1mg4mWscMQPNjBiDP9+/yA6Q72nco//CzfA=; b=Gf89uwV0jywLlH28oAwtYW2Pp3qToh1MlZfrbVSLzFKyIPh7TfD1QURZIiMgBF0rzm 25gWcoJkapXYLWQyZ4LR4pyI8RAIt7yPuBD/fBvELjTYArLg+jrkBZPSwm8Z6kNhZpAQ qPXLSkwhaEkuR/tiLX2Mz2UVODGpKuhUseuXQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=54YsztpC1mg4mWscMQPNjBiDP9+/yA6Q72nco//CzfA=; b=ToYCmUYAStLgkhyd15lzb/M2SeVUZhqhEp5nSrr4uyTTiaTOIs62a8OZ3Ic0YKqCon S8vUXNhXpvhwBgFIN+ICBJ1EZYaOSqbvfh5Owywrlvi3fzbQ66Zr1bbtOgLcFXOrtKSr auocBloW97+ZPwbQJd1oMmBw3t+n5Ssgt2dsqbjnGx7y63o3EXN8ITp1W+dnKUg5/qqp 4bcNXvHYloRfEze0ll7BIbjSYJ4LQRszCi9fmZA6yDqhyIKqdHdv2MuyHE6EmIWpszJW F8/XIfSTccic78tBKeLvX7GoYED82FSkB2cEBx3GlM0f7p7lCnPCm2Y4K+kdvoUFPufY WLFw== X-Gm-Message-State: AElRT7FQ98QfE//Lg5aKo0EhHRYhoDt4mqR8vh9xnTm3ys9y3KjC/Qrp wS0dh9BKXn88Qaz0vbnErRZxsyvz X-Google-Smtp-Source: AIpwx49cWTJXo13zWxe3vAI+Wssy9VXTQLqc7ET9cJ/k1IaDKJ2kRRglkvYHfect5IJgVyuJMSQrtA== X-Received: by 10.98.153.86 with SMTP id d83mr1265282pfe.46.1522200130704; Tue, 27 Mar 2018 18:22:10 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id y18sm4798595pfe.67.2018.03.27.18.22.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Mar 2018 18:22:09 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, roopa@cumulusnetworks.com, shm@cumulusnetworks.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, andy.roulin@gmail.com, David Ahern Subject: [PATCH net-next 3/6] net/ipv4: Move call_fib_entry_notifiers up for new routes Date: Tue, 27 Mar 2018 18:21:57 -0700 Message-Id: <20180328012200.15175-4-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com> References: <20180328012200.15175-1-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Move call to call_fib_entry_notifiers for new IPv4 routes to right before the call to fib_insert_alias. At this point the only remaining failure path is memory allocations in fib_insert_node. Handle that very unlikely failure with a call to call_fib_entry_notifiers to tell drivers about it. At this point notifier handlers can decide the fate of the new route with a clean path to delete the potential new entry if the notifier returns non-0. Signed-off-by: David Ahern Reviewed-by: Ido Schimmel --- net/ipv4/fib_trie.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index fac0b73e24d1..67116233e2bc 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1065,6 +1065,9 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, return -ENOMEM; } +/* fib notifier for ADD is sent before calling fib_insert_alias with + * the expectation that the only possible failure ENOMEM + */ static int fib_insert_alias(struct trie *t, struct key_vector *tp, struct key_vector *l, struct fib_alias *new, struct fib_alias *fa, t_key key) @@ -1263,21 +1266,32 @@ int fib_table_insert(struct net *net, struct fib_table *tb, new_fa->tb_id = tb->tb_id; new_fa->fa_default = -1; + err = call_fib_entry_notifiers(net, event, key, plen, new_fa, extack); + if (err) + goto out_free_new_fa; + /* Insert new entry to the list. */ err = fib_insert_alias(t, tp, l, new_fa, fa, key); if (err) - goto out_free_new_fa; + goto out_fib_notif; if (!plen) tb->tb_num_default++; rt_cache_flush(cfg->fc_nlinfo.nl_net); - call_fib_entry_notifiers(net, event, key, plen, new_fa, extack); rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id, &cfg->fc_nlinfo, nlflags); succeeded: return 0; +out_fib_notif: + /* notifier was sent that entry would be added to trie, but + * the add failed and need to recover. Only failure for + * fib_insert_alias is ENOMEM. + */ + NL_SET_ERR_MSG(extack, "Failed to insert route into trie"); + call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, key, + plen, new_fa, NULL); out_free_new_fa: kmem_cache_free(fn_alias_kmem, new_fa); out: From patchwork Wed Mar 28 01:21:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 891928 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="dlYmAcgh"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 409qqt51xnz9rxx for ; Wed, 28 Mar 2018 12:22:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752886AbeC1BWb (ORCPT ); Tue, 27 Mar 2018 21:22:31 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:45881 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752852AbeC1BWM (ORCPT ); Tue, 27 Mar 2018 21:22:12 -0400 Received: by mail-pl0-f67.google.com with SMTP id n15-v6so562716plp.12 for ; Tue, 27 Mar 2018 18:22:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DLpKew9R2Zr6RqWM48vaue6Pn+wqBzS7NBcWBa9Y7vU=; b=dlYmAcghwimaGW7tGZ54r7UawEogxn/8ttnCdhCvDXyb4CeGwHatS49Y89b/RMX//C RS6DGHKm6DHLqKrZfgc3YQCrWzQ632B2EWdHQEUXZKMwYYTU7sjyEuBIUmF9kPZscfJK zsN2RqRUjjEn8ATHijPBxET9d4vSgqjddtywQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DLpKew9R2Zr6RqWM48vaue6Pn+wqBzS7NBcWBa9Y7vU=; b=KpTyMRY+5Zm+P16hxfmiVp0CWsYUEYFLto8cvtR8yGw6/6fmR38aQYrOVzK31DbrOd y3Wn1V4XdPuGBbnkhlRrwQfdOxH07EfQAjRxwhfCG2M/6NpvFdNom/ycnpbETXGEuaEu 3fokrLGs7lLfmuoh56NvCmJz7zRqLLl0+bZGvmZTXqQO2MO7ZqG5nAfar66eWZOQSkF4 ym4mIwF1enTfQzpKdf8QmhxhGUlZeElTAf+X7ChNT2fngpDwdistn31XCjVqvpx92LxZ Y87Rg0kAV/YtUyTT25VfFbnLGWUedUbmwvua2ir2aiESQSQZl4ZP3tsUy2guXBqV5K9x HEfA== X-Gm-Message-State: AElRT7F7LUx5xhxoVoyYemxqH7e0Ge0jSCe3aUAwTDLgqDZgYaYZSBUK r7FjTcJb6YMibQOneoF7u60djUhy X-Google-Smtp-Source: AIpwx49DelWWwrmjL+KqMlrcHilditPYPdgIwqChYxRDHQTzxJFTSfXhnPymgBzXw7e3VFSmkd9bvg== X-Received: by 2002:a17:902:d03:: with SMTP id 3-v6mr1593240plu.245.1522200132083; Tue, 27 Mar 2018 18:22:12 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id y18sm4798595pfe.67.2018.03.27.18.22.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Mar 2018 18:22:11 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, roopa@cumulusnetworks.com, shm@cumulusnetworks.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, andy.roulin@gmail.com, David Ahern Subject: [PATCH net-next 4/6] net/ipv4: Allow notifier to fail route replace Date: Tue, 27 Mar 2018 18:21:58 -0700 Message-Id: <20180328012200.15175-5-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com> References: <20180328012200.15175-1-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add checking to call to call_fib_entry_notifiers for IPv4 route replace. Allows a notifier handler to fail the replace. Signed-off-by: David Ahern Reviewed-by: Ido Schimmel --- net/ipv4/fib_trie.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 67116233e2bc..3dcffd3ce98c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1219,8 +1219,13 @@ int fib_table_insert(struct net *net, struct fib_table *tb, new_fa->tb_id = tb->tb_id; new_fa->fa_default = -1; - call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, - key, plen, new_fa, extack); + err = call_fib_entry_notifiers(net, + FIB_EVENT_ENTRY_REPLACE, + key, plen, new_fa, + extack); + if (err) + goto out_free_new_fa; + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, &cfg->fc_nlinfo, nlflags); From patchwork Wed Mar 28 01:21:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 891925 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="hlh5wOmP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 409qqc54zFz9rxx for ; Wed, 28 Mar 2018 12:22:20 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752868AbeC1BWS (ORCPT ); Tue, 27 Mar 2018 21:22:18 -0400 Received: from mail-pl0-f68.google.com ([209.85.160.68]:39199 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752839AbeC1BWO (ORCPT ); Tue, 27 Mar 2018 21:22:14 -0400 Received: by mail-pl0-f68.google.com with SMTP id s24-v6so571877plq.6 for ; Tue, 27 Mar 2018 18:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ygWWzbZgbYkXJvSXBPv7bce9g7hi//NbpluFKlu2esU=; b=hlh5wOmPWQDkdX128nZ7tBtZmlwr3ew9NQYr+wVpOm95QGCx1UnMcy3+cBho5Z4pjE Mt+jUetD+JaQzHWt2710S4+A2FDuVxI81txKM6IH7F/+EG389NPhUnM5sCmBj5BL1KmW GY3S363ffAj0afnueiDFyLnnKqZZ+LoWNhQVU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ygWWzbZgbYkXJvSXBPv7bce9g7hi//NbpluFKlu2esU=; b=NwnPhwwKxd8KaElNm3o5h9EorKlJCGcqBfDk5AnFQlXGvDJ9DioDMGYfgh89QMKQju LJrzo4AEPT5aYXCB/TV3UJ1VGgZ3wKlna1tbnbX5PUYcLPguOoLoJ1d24Cmv+b2hdis0 0HzCWA4oBUSlWM99Tpooas3t9PyMNKvxExaGYoV5wRhp3S/2EB8z3d0FarOWN4FdXWGg p1FmwdguXQuRH0lJ6pzm6C5VzHg+vRFR791Q8q5B2cVUDmxOSmO5fQ5As3jyMSG0/rGT i6vp8d67hulCXUFbZqomIwcO0ojGNQRm+N65OsxS5XlkhWuniQfcuHG0qtvskTSb/d8d kIxQ== X-Gm-Message-State: AElRT7H/sVrX58NC4JzcjwJqLwgrVQFA9GBvkJx4DXGHw8n0Y1Y8Tbyg R1R7bUfYGJniDdnCA/b9XNaZWOK4 X-Google-Smtp-Source: AIpwx49naMaybCdVFlFgN6v3g+QFq9ourJs9DpbcRcPmAnPXYP/hk0qDOmIu0yQjj1XWJeirnVBCBA== X-Received: by 2002:a17:902:b414:: with SMTP id x20-v6mr1574813plr.165.1522200133411; Tue, 27 Mar 2018 18:22:13 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id y18sm4798595pfe.67.2018.03.27.18.22.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Mar 2018 18:22:12 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, roopa@cumulusnetworks.com, shm@cumulusnetworks.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, andy.roulin@gmail.com, David Ahern Subject: [PATCH net-next 5/6] net/ipv6: Move call_fib6_entry_notifiers up for route adds Date: Tue, 27 Mar 2018 18:21:59 -0700 Message-Id: <20180328012200.15175-6-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com> References: <20180328012200.15175-1-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Move call to call_fib6_entry_notifiers for new IPv6 routes to right before the insertion into the FIB. At this point notifier handlers can decide the fate of the new route with a clean path to delete the potential new entry if the notifier returns non-0. Signed-off-by: David Ahern Reviewed-by: Ido Schimmel --- net/ipv6/ip6_fib.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 908b8e5b615a..deab2db6692e 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1007,12 +1007,16 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (err) return err; + err = call_fib6_entry_notifiers(info->nl_net, + FIB_EVENT_ENTRY_ADD, + rt, extack); + if (err) + return err; + rcu_assign_pointer(rt->rt6_next, iter); atomic_inc(&rt->rt6i_ref); rcu_assign_pointer(rt->rt6i_node, fn); rcu_assign_pointer(*ins, rt); - call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_ADD, - rt, extack); if (!info->skip_notify) inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags); info->nl_net->ipv6.rt6_stats->fib_rt_entries++; @@ -1036,12 +1040,16 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (err) return err; + err = call_fib6_entry_notifiers(info->nl_net, + FIB_EVENT_ENTRY_REPLACE, + rt, extack); + if (err) + return err; + atomic_inc(&rt->rt6i_ref); rcu_assign_pointer(rt->rt6i_node, fn); rt->rt6_next = iter->rt6_next; rcu_assign_pointer(*ins, rt); - call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_REPLACE, - rt, extack); if (!info->skip_notify) inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE); if (!(fn->fn_flags & RTN_RTINFO)) { From patchwork Wed Mar 28 01:22:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 891926 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="g7D8Af7I"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 409qqj2XsTz9rxx for ; Wed, 28 Mar 2018 12:22:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752861AbeC1BWX (ORCPT ); Tue, 27 Mar 2018 21:22:23 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:42955 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752860AbeC1BWQ (ORCPT ); Tue, 27 Mar 2018 21:22:16 -0400 Received: by mail-pg0-f68.google.com with SMTP id f10so331322pgs.9 for ; Tue, 27 Mar 2018 18:22:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c72GEWnjClv5X7LI+yyL8IJ8Ge6UxAc8R0EOzF1vTn8=; b=g7D8Af7Izniq8nUUNdzJqWMvaeQ9fdtJEiYnNQUc4cN5spGShzjoKp2ycHAhhAi6Lg M3y9GMa1oDj/Ucez5OfTLOCTxFBdk0LRj5cSQNUsW0j6/nkKVXgGfsmAQ5Bn8ts+R8bc 8P87awowQUIpvmJCzEVKsJwLBm0pjW9o39Yf0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=c72GEWnjClv5X7LI+yyL8IJ8Ge6UxAc8R0EOzF1vTn8=; b=mpgZORE6h1qi9y5N/RJNL2NUhXMnJgcsZTLnPIYbJgnbFQvLOgdO1eiFO0Pvs8YCby qVoKG+9rRssTb/JDi8EvUIquEBUj2323nr45zxAleZ8Ejes7mabTHzyaPLx8s0dC2T2A r/AFAoVbRoN47HlczS8EkxSdCsvofgV6TdXFIoBIM7XNSFp0VAorPRLl65mDhH+7yOME 30X5+elE3pod9TlXRGA7izDhNjs1Ns2JcbjH1R3N8Yn1P2HADcHXBGFWkkJJ8+WJ5COo BDvc37sekGxycQ61voLCB1riY2RjeDEgeIZbPzzCTOcmFlpbLvdqhztNloj42d2PkeJZ WwOQ== X-Gm-Message-State: AElRT7FjWAoyyflUrQY6IswUCTR0Qw6cYPXjYJxN/ygA5LpGl+7lyebu Hlu26j+7nin6XBzxBkvWy+4kfa8l X-Google-Smtp-Source: AIpwx4+/U5XmmxqXE4aRJZuPz9zb6CK7C8U9Nek7m47R+mD3Urv/JFzv6iZ+G24nOy3NmagLEqpYTQ== X-Received: by 10.98.11.149 with SMTP id 21mr1251508pfl.64.1522200134754; Tue, 27 Mar 2018 18:22:14 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id y18sm4798595pfe.67.2018.03.27.18.22.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Mar 2018 18:22:13 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, roopa@cumulusnetworks.com, shm@cumulusnetworks.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, andy.roulin@gmail.com, David Ahern Subject: [PATCH net-next 6/6] netdevsim: Add simple FIB resource controller via devlink Date: Tue, 27 Mar 2018 18:22:00 -0700 Message-Id: <20180328012200.15175-7-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com> References: <20180328012200.15175-1-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add devlink support to netdevsim and use it to implement a simple, profile based resource controller. Only one controller is needed per namespace, so the first netdevsim netdevice in a namespace registers with devlink. If that device is deleted, the resource settings are deleted. The resource controller allows a user to limit the number of IPv4 and IPv6 FIB entries and FIB rules. The resource paths are: /IPv4 /IPv4/fib /IPv4/fib-rules /IPv6 /IPv6/fib /IPv6/fib-rules The IPv4 and IPv6 top level resources are unlimited in size and can not be changed. From there, the number of FIB entries and FIB rule entries are unlimited by default. A user can specify a limit for the fib and fib-rules resources: $ devlink resource set netdevsim/netdevsim0 path /IPv4/fib size 96 $ devlink resource set netdevsim/netdevsim0 path /IPv4/fib-rules size 16 $ devlink resource set netdevsim/netdevsim0 path /IPv6/fib size 64 $ devlink resource set netdevsim/netdevsim0 path /IPv6/fib-rules size 16 $ devlink dev reload netdevsim/netdevsim0 such that the number of rules or routes is limited (96 ipv4 routes in the example above): $ for n in $(seq 1 32); do ip ro add 10.99.$n.0/24 dev eth1; done Error: netdevsim: Exceeded number of supported fib entries. $ devlink resource show netdevsim/netdevsim0 netdevsim/netdevsim0: name IPv4 size unlimited unit entry size_min 0 size_max unlimited size_gran 1 dpipe_tables non resources: name fib size 96 occ 96 unit entry size_min 0 size_max unlimited size_gran 1 dpipe_tables ... With this template in place for resource management, it is fairly trivial to extend and shows one way to implement a simple counter based resource controller typical of network profiles. Currently, devlink only supports initial namespace. Code is in place to adapt netdevsim to a per namespace controller once the network namespace issues are resolved. Signed-off-by: David Ahern --- drivers/net/Kconfig | 1 + drivers/net/netdevsim/Makefile | 4 + drivers/net/netdevsim/devlink.c | 294 ++++++++++++++++++++++++++++++++++++++ drivers/net/netdevsim/fib.c | 263 ++++++++++++++++++++++++++++++++++ drivers/net/netdevsim/netdev.c | 12 +- drivers/net/netdevsim/netdevsim.h | 43 ++++++ 6 files changed, 616 insertions(+), 1 deletion(-) create mode 100644 drivers/net/netdevsim/devlink.c create mode 100644 drivers/net/netdevsim/fib.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 08b85215c2be..891846655000 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -500,6 +500,7 @@ source "drivers/net/hyperv/Kconfig" config NETDEVSIM tristate "Simulated networking device" depends on DEBUG_FS + depends on MAY_USE_DEVLINK help This driver is a developer testing tool and software model that can be used to test various control path networking APIs, especially diff --git a/drivers/net/netdevsim/Makefile b/drivers/net/netdevsim/Makefile index 09388c06171d..449b2a1a1800 100644 --- a/drivers/net/netdevsim/Makefile +++ b/drivers/net/netdevsim/Makefile @@ -9,3 +9,7 @@ ifeq ($(CONFIG_BPF_SYSCALL),y) netdevsim-objs += \ bpf.o endif + +ifneq ($(CONFIG_NET_DEVLINK),) +netdevsim-objs += devlink.o fib.o +endif diff --git a/drivers/net/netdevsim/devlink.c b/drivers/net/netdevsim/devlink.c new file mode 100644 index 000000000000..bbdcf064ba10 --- /dev/null +++ b/drivers/net/netdevsim/devlink.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2018 Cumulus Networks. All rights reserved. + * Copyright (c) 2018 David Ahern + * + * This software is licensed under the GNU General License Version 2, + * June 1991 as shown in the file COPYING in the top-level directory of this + * source tree. + * + * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME + * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + */ + +#include +#include +#include + +#include "netdevsim.h" + +static unsigned int nsim_devlink_id; + +/* place holder until devlink and namespaces is sorted out */ +static struct net *nsim_devlink_net(struct devlink *devlink) +{ + return &init_net; +} + +/* IPv4 + */ +static u64 nsim_ipv4_fib_resource_occ_get(struct devlink *devlink) +{ + struct net *net = nsim_devlink_net(devlink); + + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false); +} + +static struct devlink_resource_ops nsim_ipv4_fib_res_ops = { + .occ_get = nsim_ipv4_fib_resource_occ_get, +}; + +static u64 nsim_ipv4_fib_rules_res_occ_get(struct devlink *devlink) +{ + struct net *net = nsim_devlink_net(devlink); + + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false); +} + +static struct devlink_resource_ops nsim_ipv4_fib_rules_res_ops = { + .occ_get = nsim_ipv4_fib_rules_res_occ_get, +}; + +/* IPv6 + */ +static u64 nsim_ipv6_fib_resource_occ_get(struct devlink *devlink) +{ + struct net *net = nsim_devlink_net(devlink); + + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false); +} + +static struct devlink_resource_ops nsim_ipv6_fib_res_ops = { + .occ_get = nsim_ipv6_fib_resource_occ_get, +}; + +static u64 nsim_ipv6_fib_rules_res_occ_get(struct devlink *devlink) +{ + struct net *net = nsim_devlink_net(devlink); + + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false); +} + +static struct devlink_resource_ops nsim_ipv6_fib_rules_res_ops = { + .occ_get = nsim_ipv6_fib_rules_res_occ_get, +}; + +static int devlink_resources_register(struct devlink *devlink) +{ + struct devlink_resource_size_params params = { + .size_max = (u64)-1, + .size_granularity = 1, + .unit = DEVLINK_RESOURCE_UNIT_ENTRY + }; + struct net *net = nsim_devlink_net(devlink); + int err; + u64 n; + + /* Resources for IPv4 */ + err = devlink_resource_register(devlink, "IPv4", (u64)-1, + NSIM_RESOURCE_IPV4, + DEVLINK_RESOURCE_ID_PARENT_TOP, + ¶ms, NULL); + if (err) { + pr_err("Failed to register IPv4 top resource\n"); + goto out; + } + + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true); + err = devlink_resource_register(devlink, "fib", n, + NSIM_RESOURCE_IPV4_FIB, + NSIM_RESOURCE_IPV4, + ¶ms, &nsim_ipv4_fib_res_ops); + if (err) { + pr_err("Failed to register IPv4 FIB resource\n"); + return err; + } + + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true); + err = devlink_resource_register(devlink, "fib-rules", n, + NSIM_RESOURCE_IPV4_FIB_RULES, + NSIM_RESOURCE_IPV4, + ¶ms, &nsim_ipv4_fib_rules_res_ops); + if (err) { + pr_err("Failed to register IPv4 FIB rules resource\n"); + return err; + } + + /* Resources for IPv6 */ + err = devlink_resource_register(devlink, "IPv6", (u64)-1, + NSIM_RESOURCE_IPV6, + DEVLINK_RESOURCE_ID_PARENT_TOP, + ¶ms, NULL); + if (err) { + pr_err("Failed to register IPv6 top resource\n"); + goto out; + } + + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true); + err = devlink_resource_register(devlink, "fib", n, + NSIM_RESOURCE_IPV6_FIB, + NSIM_RESOURCE_IPV6, + ¶ms, &nsim_ipv6_fib_res_ops); + if (err) { + pr_err("Failed to register IPv6 FIB resource\n"); + return err; + } + + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true); + err = devlink_resource_register(devlink, "fib-rules", n, + NSIM_RESOURCE_IPV6_FIB_RULES, + NSIM_RESOURCE_IPV6, + ¶ms, &nsim_ipv6_fib_rules_res_ops); + if (err) { + pr_err("Failed to register IPv6 FIB rules resource\n"); + return err; + } +out: + return err; +} + +static int nsim_devlink_reload(struct devlink *devlink) +{ + enum nsim_resource_id res_ids[] = { + NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, + NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES + }; + struct net *net = nsim_devlink_net(devlink); + int i; + + for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { + int err; + u64 val; + + err = devlink_resource_size_get(devlink, res_ids[i], &val); + if (!err) { + err = nsim_fib_set_max(net, res_ids[i], val); + if (err) + return err; + } + } + + return 0; +} + +static void nsim_devlink_net_reset(struct net *net) +{ + enum nsim_resource_id res_ids[] = { + NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, + NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES + }; + int i; + + for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { + if (nsim_fib_set_max(net, res_ids[i], (u64)-1)) { + pr_err("Failed to reset limit for resource %u\n", + res_ids[i]); + } + } +} + +static const struct devlink_ops nsim_devlink_ops = { + .reload = nsim_devlink_reload, +}; + +/* once devlink / namespace issues are sorted out + * this needs to be net in which a devlink instance + * is to be created. e.g., dev_net(ns->netdev) + */ +static struct net *nsim_to_net(struct netdevsim *ns) +{ + return &init_net; +} + +void nsim_devlink_teardown(struct netdevsim *ns) +{ + if (ns->devlink) { + struct net *net = nsim_to_net(ns); + bool *reg_devlink = net_generic(net, nsim_devlink_id); + + devlink_unregister(ns->devlink); + devlink_free(ns->devlink); + ns->devlink = NULL; + + nsim_devlink_net_reset(net); + *reg_devlink = true; + } +} + +void nsim_devlink_setup(struct netdevsim *ns) +{ + struct net *net = nsim_to_net(ns); + bool *reg_devlink = net_generic(net, nsim_devlink_id); + struct devlink *devlink; + int err = -ENOMEM; + + /* only one device per namespace controls devlink */ + if (!*reg_devlink) { + ns->devlink = NULL; + return; + } + + devlink = devlink_alloc(&nsim_devlink_ops, 0); + if (!devlink) + return; + + err = devlink_register(devlink, &ns->dev); + if (err) + goto err_devlink_free; + + err = devlink_resources_register(devlink); + if (err) + goto err_dl_unregister; + + ns->devlink = devlink; + + *reg_devlink = false; + + return; + +err_dl_unregister: + devlink_unregister(devlink); +err_devlink_free: + devlink_free(devlink); +} + +/* Initialize per network namespace state */ +static int __net_init nsim_devlink_netns_init(struct net *net) +{ + bool *reg_devlink = net_generic(net, nsim_devlink_id); + + *reg_devlink = true; + + return 0; +} + +static struct pernet_operations nsim_devlink_net_ops __net_initdata = { + .init = nsim_devlink_netns_init, + .id = &nsim_devlink_id, + .size = sizeof(bool), +}; + +void nsim_devlink_exit(void) +{ + unregister_pernet_subsys(&nsim_devlink_net_ops); + nsim_fib_exit(); +} + +int nsim_devlink_init(void) +{ + int err; + + err = nsim_fib_init(); + if (err) + goto err_out; + + err = register_pernet_subsys(&nsim_devlink_net_ops); + if (err) + nsim_fib_exit(); + +err_out: + return err; +} diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c new file mode 100644 index 000000000000..0d105bafa261 --- /dev/null +++ b/drivers/net/netdevsim/fib.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2018 Cumulus Networks. All rights reserved. + * Copyright (c) 2018 David Ahern + * + * This software is licensed under the GNU General License Version 2, + * June 1991 as shown in the file COPYING in the top-level directory of this + * source tree. + * + * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME + * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + */ + +#include +#include +#include +#include +#include + +#include "netdevsim.h" + +struct nsim_fib_entry { + u64 max; + u64 num; +}; + +struct nsim_per_fib_data { + struct nsim_fib_entry fib; + struct nsim_fib_entry rules; +}; + +struct nsim_fib_data { + struct nsim_per_fib_data ipv4; + struct nsim_per_fib_data ipv6; +}; + +static unsigned int nsim_fib_net_id; + +u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max) +{ + struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); + struct nsim_fib_entry *entry; + + switch (res_id) { + case NSIM_RESOURCE_IPV4_FIB: + entry = &fib_data->ipv4.fib; + break; + case NSIM_RESOURCE_IPV4_FIB_RULES: + entry = &fib_data->ipv4.rules; + break; + case NSIM_RESOURCE_IPV6_FIB: + entry = &fib_data->ipv6.fib; + break; + case NSIM_RESOURCE_IPV6_FIB_RULES: + entry = &fib_data->ipv6.rules; + break; + default: + return 0; + } + + return max ? entry->max : entry->num; +} + +int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val) +{ + struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); + struct nsim_fib_entry *entry; + int err = 0; + + switch (res_id) { + case NSIM_RESOURCE_IPV4_FIB: + entry = &fib_data->ipv4.fib; + break; + case NSIM_RESOURCE_IPV4_FIB_RULES: + entry = &fib_data->ipv4.rules; + break; + case NSIM_RESOURCE_IPV6_FIB: + entry = &fib_data->ipv6.fib; + break; + case NSIM_RESOURCE_IPV6_FIB_RULES: + entry = &fib_data->ipv6.rules; + break; + default: + return 0; + } + + /* not allowing a new max to be less than curren occupancy + * --> no means of evicting entries + */ + if (val < entry->num) + err = -EINVAL; + else + entry->max = val; + + return err; +} + +static int nsim_fib_rule_account(struct nsim_fib_entry *entry, bool add, + struct netlink_ext_ack *extack) +{ + int err = 0; + + if (add) { + if (entry->num < entry->max) { + entry->num++; + } else { + err = -ENOSPC; + NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported fib rule entries"); + } + } else { + entry->num--; + } + + return err; +} + +static int nsim_fib_rule_event(struct fib_notifier_info *info, bool add) +{ + struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); + struct netlink_ext_ack *extack = info->extack; + int err = 0; + + switch (info->family) { + case AF_INET: + err = nsim_fib_rule_account(&data->ipv4.rules, add, extack); + break; + case AF_INET6: + err = nsim_fib_rule_account(&data->ipv6.rules, add, extack); + break; + } + + return err; +} + +static int nsim_fib_account(struct nsim_fib_entry *entry, bool add, + struct netlink_ext_ack *extack) +{ + int err = 0; + + if (add) { + if (entry->num < entry->max) { + entry->num++; + } else { + err = -ENOSPC; + NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported fib entries"); + } + } else { + entry->num--; + } + + return err; +} + +static int nsim_fib_event(struct fib_notifier_info *info, bool add) +{ + struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); + struct netlink_ext_ack *extack = info->extack; + int err = 0; + + switch (info->family) { + case AF_INET: + err = nsim_fib_account(&data->ipv4.fib, add, extack); + break; + case AF_INET6: + err = nsim_fib_account(&data->ipv6.fib, add, extack); + break; + } + + return err; +} + +static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, + void *ptr) +{ + struct fib_notifier_info *info = ptr; + int err = 0; + + switch (event) { + case FIB_EVENT_RULE_ADD: /* fall through */ + case FIB_EVENT_RULE_DEL: + err = nsim_fib_rule_event(info, event == FIB_EVENT_RULE_ADD); + break; + + case FIB_EVENT_ENTRY_ADD: /* fall through */ + case FIB_EVENT_ENTRY_DEL: + err = nsim_fib_event(info, event == FIB_EVENT_ENTRY_ADD); + break; + } + + return notifier_from_errno(err); +} + +/* inconsistent dump, trying again */ +static void nsim_fib_dump_inconsistent(struct notifier_block *nb) +{ + struct nsim_fib_data *data; + struct net *net; + + rcu_read_lock(); + for_each_net_rcu(net) { + data = net_generic(net, nsim_fib_net_id); + + data->ipv4.fib.num = 0ULL; + data->ipv4.rules.num = 0ULL; + + data->ipv6.fib.num = 0ULL; + data->ipv6.rules.num = 0ULL; + } + rcu_read_unlock(); +} + +static struct notifier_block nsim_fib_nb = { + .notifier_call = nsim_fib_event_nb, +}; + +/* Initialize per network namespace state */ +static int __net_init nsim_fib_netns_init(struct net *net) +{ + struct nsim_fib_data *data = net_generic(net, nsim_fib_net_id); + + data->ipv4.fib.max = (u64)-1; + data->ipv4.rules.max = (u64)-1; + + data->ipv6.fib.max = (u64)-1; + data->ipv6.rules.max = (u64)-1; + + return 0; +} + +static struct pernet_operations nsim_fib_net_ops __net_initdata = { + .init = nsim_fib_netns_init, + .id = &nsim_fib_net_id, + .size = sizeof(struct nsim_fib_data), +}; + +void nsim_fib_exit(void) +{ + unregister_pernet_subsys(&nsim_fib_net_ops); + unregister_fib_notifier(&nsim_fib_nb); +} + +int nsim_fib_init(void) +{ + int err; + + err = register_pernet_subsys(&nsim_fib_net_ops); + if (err < 0) { + pr_err("Failed to register pernet subsystem\n"); + goto err_out; + } + + err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent); + if (err < 0) { + pr_err("Failed to register fib notifier\n"); + goto err_out; + } + +err_out: + return err; +} diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 3fd567928f3d..8b30ab3ea2c2 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -167,6 +167,8 @@ static int nsim_init(struct net_device *dev) SET_NETDEV_DEV(dev, &ns->dev); + nsim_devlink_setup(ns); + return 0; err_bpf_uninit: @@ -180,6 +182,7 @@ static void nsim_uninit(struct net_device *dev) { struct netdevsim *ns = netdev_priv(dev); + nsim_devlink_teardown(ns); debugfs_remove_recursive(ns->ddir); nsim_bpf_uninit(ns); } @@ -478,12 +481,18 @@ static int __init nsim_module_init(void) if (err) goto err_debugfs_destroy; - err = rtnl_link_register(&nsim_link_ops); + err = nsim_devlink_init(); if (err) goto err_unreg_bus; + err = rtnl_link_register(&nsim_link_ops); + if (err) + goto err_dl_fini; + return 0; +err_dl_fini: + nsim_devlink_exit(); err_unreg_bus: bus_unregister(&nsim_bus); err_debugfs_destroy: @@ -494,6 +503,7 @@ static int __init nsim_module_init(void) static void __exit nsim_module_exit(void) { rtnl_link_unregister(&nsim_link_ops); + nsim_devlink_exit(); bus_unregister(&nsim_bus); debugfs_remove_recursive(nsim_ddir); } diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index ea081c10efb8..afb8cf90c0fd 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -64,6 +64,9 @@ struct netdevsim { bool bpf_map_accept; struct list_head bpf_bound_maps; +#if IS_ENABLED(CONFIG_NET_DEVLINK) + struct devlink *devlink; +#endif }; extern struct dentry *nsim_ddir; @@ -103,6 +106,46 @@ nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } #endif +#if IS_ENABLED(CONFIG_NET_DEVLINK) +enum nsim_resource_id { + NSIM_RESOURCE_NONE, /* DEVLINK_RESOURCE_ID_PARENT_TOP */ + NSIM_RESOURCE_IPV4, + NSIM_RESOURCE_IPV4_FIB, + NSIM_RESOURCE_IPV4_FIB_RULES, + NSIM_RESOURCE_IPV6, + NSIM_RESOURCE_IPV6_FIB, + NSIM_RESOURCE_IPV6_FIB_RULES, +}; + +void nsim_devlink_setup(struct netdevsim *ns); +void nsim_devlink_teardown(struct netdevsim *ns); + +int nsim_devlink_init(void); +void nsim_devlink_exit(void); + +int nsim_fib_init(void); +void nsim_fib_exit(void); +u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); +int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val); +#else +static inline void nsim_devlink_setup(struct netdevsim *ns) +{ +} + +static inline void nsim_devlink_teardown(struct netdevsim *ns) +{ +} + +static inline int nsim_devlink_init(void) +{ + return 0; +} + +static inline void nsim_devlink_exit(void) +{ +} +#endif + static inline struct netdevsim *to_nsim(struct device *ptr) { return container_of(ptr, struct netdevsim, dev);