From patchwork Fri Dec 15 18:27:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849351 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="xyBLuNwq"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzT54PNFz9sBW for ; Sat, 16 Dec 2017 05:28:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755977AbdLOS2X (ORCPT ); Fri, 15 Dec 2017 13:28:23 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:44255 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755718AbdLOS2W (ORCPT ); Fri, 15 Dec 2017 13:28:22 -0500 Received: by mail-pg0-f67.google.com with SMTP id j9so6316609pgc.11 for ; Fri, 15 Dec 2017 10:28:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jo8jIUE/tFvyqeE43NOJWn0uMeIXkTrwbYkczfk/I4k=; b=xyBLuNwq5IgB1YcBSOy6R5M5/kyozclkSw6rMvjukx01mYjF+RrrFBmaVtPxD0PuHv 4IsADjto4Bq6/WFzI/W4/kHMYu0DMNJQxgU2HgumHINgjv5Mftr3eWC0SZOXv+M7YSS8 xcuvuRZb6dSi+2hYbX1IH6z4lZPu7egPnqKbx0iFm5xyYeosclaxoQGxVU4CRMeJ1tXd 23l/NYomT78JkCEsV2HVrqfZU+wrZhENExXCXyVifCb9/9DNeubRQ6+fpSx4kJB1lR2y 8LPUTW6mBaaWx40QjilbpUmYookzbgFkrooQ3Em67UHea99b9peOQ1TcH4h/ZvwoaImn BCdw== 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=jo8jIUE/tFvyqeE43NOJWn0uMeIXkTrwbYkczfk/I4k=; b=hKixbk3UL5iBnBb1MOQC/oHuyfuHnKKJzdOLN7QMXX9zgk7OuSOBTC/G207YAv8SB5 nAHvSb+ps4wpaQA883qpyDEoC+U92yUqqijvFiJp4WyinTVXH0Xihc43KGHfKMlXJfUb RSOjX0kgkedGhfvXyuUPi9ykECkWwASzwpGVle8tKPZ3gNcX5rtfwFOr9h06rzHxFjoI fMblqZBva6og8/8OSoax3yXJFDw8tUphw1LrGtAapFsGFYYHE13DBsXbVRqQUc3YdnWt mg/YR8Ot2U2TxyL91khrIGPeUzC8aYmvc6jLsp64qAKw+ImpsWxaQa7fPqYPM/CPxT5Z dgUA== X-Gm-Message-State: AKGB3mIyu6HRpEgVNgEBl0JLO8fxOJInVVNy1SPCNFFHRrZOpuhJXwa+ 3ziKWy3q/2Z5PH5yd2FVckqdjw== X-Google-Smtp-Source: ACJfBouFmq+SHRZ3SHxiXy2Lr9Yar7uk+2lMJJBma5JhJLHjXxpbpZoGovq/D+IGkfM6PXWfywU0zA== X-Received: by 10.99.150.9 with SMTP id c9mr12675255pge.386.1513362501352; Fri, 15 Dec 2017 10:28:21 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:20 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Date: Fri, 15 Dec 2017 10:27:55 -0800 Message-Id: <20171215182800.10248-2-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Users of LWT need to know net if they want to have per net operations in LWT. Signed-off-by: Tom Herbert Acked-by: Roopa Prabhu --- include/net/lwtunnel.h | 6 +++--- net/core/lwt_bpf.c | 2 +- net/core/lwtunnel.c | 4 ++-- net/ipv4/fib_semantics.c | 13 ++++++++----- net/ipv4/ip_tunnel_core.c | 4 ++-- net/ipv6/ila/ila_lwt.c | 2 +- net/ipv6/route.c | 2 +- net/ipv6/seg6_iptunnel.c | 2 +- net/ipv6/seg6_local.c | 5 +++-- net/mpls/mpls_iptunnel.c | 2 +- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h index d747ef975cd8..da5e51e0d122 100644 --- a/include/net/lwtunnel.h +++ b/include/net/lwtunnel.h @@ -34,7 +34,7 @@ struct lwtunnel_state { }; struct lwtunnel_encap_ops { - int (*build_state)(struct nlattr *encap, + int (*build_state)(struct net *net, struct nlattr *encap, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack); @@ -113,7 +113,7 @@ int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack); int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len, struct netlink_ext_ack *extack); -int lwtunnel_build_state(u16 encap_type, +int lwtunnel_build_state(struct net *net, u16 encap_type, struct nlattr *encap, unsigned int family, const void *cfg, struct lwtunnel_state **lws, @@ -192,7 +192,7 @@ static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len, return 0; } -static inline int lwtunnel_build_state(u16 encap_type, +static inline int lwtunnel_build_state(struct net *net, u16 encap_type, struct nlattr *encap, unsigned int family, const void *cfg, struct lwtunnel_state **lws, diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index e7e626fb87bb..3a3ac13fcf06 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c @@ -238,7 +238,7 @@ static const struct nla_policy bpf_nl_policy[LWT_BPF_MAX + 1] = { [LWT_BPF_XMIT_HEADROOM] = { .type = NLA_U32 }, }; -static int bpf_build_state(struct nlattr *nla, +static int bpf_build_state(struct net *net, struct nlattr *nla, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 0b171756453c..b3f2f77dfe72 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -103,7 +103,7 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops, } EXPORT_SYMBOL_GPL(lwtunnel_encap_del_ops); -int lwtunnel_build_state(u16 encap_type, +int lwtunnel_build_state(struct net *net, u16 encap_type, struct nlattr *encap, unsigned int family, const void *cfg, struct lwtunnel_state **lws, struct netlink_ext_ack *extack) @@ -124,7 +124,7 @@ int lwtunnel_build_state(u16 encap_type, ops = rcu_dereference(lwtun_encaps[encap_type]); if (likely(ops && ops->build_state && try_module_get(ops->owner))) { found = true; - ret = ops->build_state(encap, family, cfg, lws, extack); + ret = ops->build_state(net, encap, family, cfg, lws, extack); if (ret) module_put(ops->owner); } diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index f04d944f8abe..4979e5c6b9b8 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -523,6 +523,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh, if (nla) { struct lwtunnel_state *lwtstate; struct nlattr *nla_entype; + struct net *net = cfg->fc_nlinfo.nl_net; nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE); @@ -533,7 +534,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh, goto err_inval; } - ret = lwtunnel_build_state(nla_get_u16( + ret = lwtunnel_build_state(net, nla_get_u16( nla_entype), nla, AF_INET, cfg, &lwtstate, extack); @@ -607,7 +608,7 @@ static void fib_rebalance(struct fib_info *fi) #endif /* CONFIG_IP_ROUTE_MULTIPATH */ -static int fib_encap_match(u16 encap_type, +static int fib_encap_match(struct net *net, u16 encap_type, struct nlattr *encap, const struct fib_nh *nh, const struct fib_config *cfg, @@ -619,7 +620,7 @@ static int fib_encap_match(u16 encap_type, if (encap_type == LWTUNNEL_ENCAP_NONE) return 0; - ret = lwtunnel_build_state(encap_type, encap, AF_INET, + ret = lwtunnel_build_state(net, encap_type, encap, AF_INET, cfg, &lwtstate, extack); if (!ret) { result = lwtunnel_cmp_encap(lwtstate, nh->nh_lwtstate); @@ -632,6 +633,7 @@ static int fib_encap_match(u16 encap_type, int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, struct netlink_ext_ack *extack) { + struct net *net = cfg->fc_nlinfo.nl_net; #ifdef CONFIG_IP_ROUTE_MULTIPATH struct rtnexthop *rtnh; int remaining; @@ -642,7 +644,8 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, if (cfg->fc_oif || cfg->fc_gw) { if (cfg->fc_encap) { - if (fib_encap_match(cfg->fc_encap_type, cfg->fc_encap, + if (fib_encap_match(net, cfg->fc_encap_type, + cfg->fc_encap, fi->fib_nh, cfg, extack)) return 1; } @@ -1180,7 +1183,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, "LWT encap type not specified"); goto err_inval; } - err = lwtunnel_build_state(cfg->fc_encap_type, + err = lwtunnel_build_state(net, cfg->fc_encap_type, cfg->fc_encap, AF_INET, cfg, &lwtstate, extack); if (err) diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 2f39479be92f..32e05aa6117d 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -228,7 +228,7 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = { [LWTUNNEL_IP_FLAGS] = { .type = NLA_U16 }, }; -static int ip_tun_build_state(struct nlattr *attr, +static int ip_tun_build_state(struct net *net, struct nlattr *attr, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) @@ -327,7 +327,7 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = { [LWTUNNEL_IP6_FLAGS] = { .type = NLA_U16 }, }; -static int ip6_tun_build_state(struct nlattr *attr, +static int ip6_tun_build_state(struct net *net, struct nlattr *attr, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c index 3d56a2fb6f86..9f1e46a1468e 100644 --- a/net/ipv6/ila/ila_lwt.c +++ b/net/ipv6/ila/ila_lwt.c @@ -125,7 +125,7 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { [ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, }, }; -static int ila_build_state(struct nlattr *nla, +static int ila_build_state(struct net *net, struct nlattr *nla, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b3f4d19b3ca5..0e0cc97e8f42 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2565,7 +2565,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, if (cfg->fc_encap) { struct lwtunnel_state *lwtstate; - err = lwtunnel_build_state(cfg->fc_encap_type, + err = lwtunnel_build_state(net, cfg->fc_encap_type, cfg->fc_encap, AF_INET6, cfg, &lwtstate, extack); if (err) diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index bd6cc688bd19..a6cf2fba15f3 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c @@ -359,7 +359,7 @@ static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb) return err; } -static int seg6_build_state(struct nlattr *nla, +static int seg6_build_state(struct net *net, struct nlattr *nla, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 825b8e01f947..45dc670c5a93 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -779,8 +779,9 @@ static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt) return 0; } -static int seg6_local_build_state(struct nlattr *nla, unsigned int family, - const void *cfg, struct lwtunnel_state **ts, +static int seg6_local_build_state(struct net *net, struct nlattr *nla, + unsigned int family, const void *cfg, + struct lwtunnel_state **ts, struct netlink_ext_ack *extack) { struct nlattr *tb[SEG6_LOCAL_MAX + 1]; diff --git a/net/mpls/mpls_iptunnel.c b/net/mpls/mpls_iptunnel.c index 6e558a419f60..c947310cc04f 100644 --- a/net/mpls/mpls_iptunnel.c +++ b/net/mpls/mpls_iptunnel.c @@ -157,7 +157,7 @@ static int mpls_xmit(struct sk_buff *skb) return -EINVAL; } -static int mpls_build_state(struct nlattr *nla, +static int mpls_build_state(struct net *net, struct nlattr *nla, unsigned int family, const void *cfg, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) From patchwork Fri Dec 15 18:27:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849352 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="IFeg56C/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzTB342Jz9sBW for ; Sat, 16 Dec 2017 05:28:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755593AbdLOS22 (ORCPT ); Fri, 15 Dec 2017 13:28:28 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:37071 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755718AbdLOS2Y (ORCPT ); Fri, 15 Dec 2017 13:28:24 -0500 Received: by mail-pg0-f66.google.com with SMTP id y6so6326069pgp.4 for ; Fri, 15 Dec 2017 10:28:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jwT+TnJm6MIjhfEezGe/IPzlPxZo7MRK4Um1X8VcOtg=; b=IFeg56C/66/It+hD8KEt/ky/5v+l58vOgzXqbsZw3dYdHwMbUz7RAqD89cXB+qpoPH vQ2adGSXuDbR+ciFkJ3nJq71BQb18SGybcOlshq9NUT5uefdg7TE4lYaN9Eexsh+o7zH GW5V9tWl2TQTAh98gHEdiYl53dnOhSmWgoesDq2sKQJkVfRGGJGVW7vFg2vkcXx65k4c 4aGTjByyFFvyui62F1T/iIORzImKoGGDtZKSrRpCa4ALV7JzZlFQ8F0VSCO7Pd9caQwe nxOAYkiXnWszukuL4RXqRmvaBDEGG4Yne9wgB5gxsC/vSG7WDjd8iCQehxGmFLALwC70 qPIA== 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=jwT+TnJm6MIjhfEezGe/IPzlPxZo7MRK4Um1X8VcOtg=; b=XXlcqKEtaje1iNff4NtXXYz8YwAkUztC3TxzyOZ5G1tTGyYGgsPeTFpaztLRJ2p2U5 SMJhA8fIo68ejsy2kz3KlVLvx7qhI4Fj03BSP8BqYu1UmRJQYLrWzViQK11wjEdBH6ej bI/kTwwOvkiskxvHvv4sH6HF+toZvKCRGlfo5cX2IRVkFY6zF6BLeZ7qlnF/hGMd6IUj 7dPIK7mZhE07atsyU3idcTyynsO+hX+nIXsI9T2mqyYwW1mw4j49jUmPjb0In58cbXV3 QSnOeReM59bpZjnmWxWNfcL6is0RHo3lL2tEtU6TjseN7TGz/P8ggzsnxtdN4efL2ldA +Imw== X-Gm-Message-State: AKGB3mJU4hTw7JyT9L7nXMwoTpY0FDYnCzpmkbLR7S7mb1gVFbmIVcsR a4bz5R9x6xO/So/58ttwWf84bZmg X-Google-Smtp-Source: ACJfBouvVhaBTWFG7/H5sV60oaxJdTjIIxWAjWaoAkGoyLaChe7N+Vgt6wksu4e3Xhw4nT4yQo0G6Q== X-Received: by 10.98.213.71 with SMTP id d68mr13888412pfg.171.1513362504346; Fri, 15 Dec 2017 10:28:24 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:23 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 2/6] ila: Fix use of rhashtable walk in ila_xlat.c Date: Fri, 15 Dec 2017 10:27:56 -0800 Message-Id: <20171215182800.10248-3-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Perform better EAGAIN handling, handle case where ila_dump_info fails and we missed objects in the dump, and add a skip index to skip over ila entires in a list on a rhashtable node that have already been visited (by a previous call to ila_nl_dump). Signed-off-by: Tom Herbert --- net/ipv6/ila/ila_xlat.c | 70 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 44c39c5f0638..887dd5b785b5 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -474,24 +474,31 @@ static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info) struct ila_dump_iter { struct rhashtable_iter rhiter; + int skip; }; static int ila_nl_dump_start(struct netlink_callback *cb) { struct net *net = sock_net(cb->skb->sk); struct ila_net *ilan = net_generic(net, ila_net_id); - struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0]; + struct ila_dump_iter *iter; + int ret; - if (!iter) { - iter = kmalloc(sizeof(*iter), GFP_KERNEL); - if (!iter) - return -ENOMEM; + iter = kmalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + return -ENOMEM; - cb->args[0] = (long)iter; + ret = rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter, + GFP_KERNEL); + if (ret) { + kfree(iter); + return ret; } - return rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter, - GFP_KERNEL); + iter->skip = 0; + cb->args[0] = (long)iter; + + return ret; } static int ila_nl_dump_done(struct netlink_callback *cb) @@ -509,20 +516,45 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0]; struct rhashtable_iter *rhiter = &iter->rhiter; + int skip = iter->skip; struct ila_map *ila; int ret; rhashtable_walk_start(rhiter); - for (;;) { - ila = rhashtable_walk_next(rhiter); + /* Get first entry */ + ila = rhashtable_walk_peek(rhiter); + + if (ila && !IS_ERR(ila) && skip) { + /* Skip over visited entries */ + + while (ila && skip) { + /* Skip over any ila entries in this list that we + * have already dumped. + */ + ila = rcu_access_pointer(ila->next); + skip--; + } + } + skip = 0; + + for (;;) { if (IS_ERR(ila)) { - if (PTR_ERR(ila) == -EAGAIN) - continue; ret = PTR_ERR(ila); - goto done; + if (ret == -EAGAIN) { + /* Table has changed and iter has reset. Return + * -EAGAIN to the application even if we have + * written data to the skb. The application + * needs to deal with this. + */ + + goto out_ret; + } else { + break; + } } else if (!ila) { + ret = 0; break; } @@ -531,15 +563,21 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb) cb->nlh->nlmsg_seq, NLM_F_MULTI, skb, ILA_CMD_GET); if (ret) - goto done; + goto out; + skip++; ila = rcu_access_pointer(ila->next); } + + skip = 0; + ila = rhashtable_walk_next(rhiter); } - ret = skb->len; +out: + iter->skip = skip; + ret = (skb->len ? : ret); -done: +out_ret: rhashtable_walk_stop(rhiter); return ret; } From patchwork Fri Dec 15 18:27:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849353 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="Jp/PqCv6"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzTF41wCz9sBW for ; Sat, 16 Dec 2017 05:28:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756267AbdLOS2a (ORCPT ); Fri, 15 Dec 2017 13:28:30 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:45122 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756195AbdLOS21 (ORCPT ); Fri, 15 Dec 2017 13:28:27 -0500 Received: by mail-pf0-f194.google.com with SMTP id u19so6694057pfa.12 for ; Fri, 15 Dec 2017 10:28:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9dJ8ZbNRJip1W5R3juPd6Pbw/xeNyvq4XqNXo9NadZo=; b=Jp/PqCv6jSQkBKs4Xs4gks+QeeZtU/HP2Df/f9Ee2Q3+71tEHdkd/+kcX/QuoxzjWm ElVp2WcLEQgtHusnZwpgmrMpn0uOrqdJolUxeBEBsPRQbTwR0Q4N4NmgT2SP6sEnOnXM z+cSWlGJm0uCtAItTNE28c6MOS8C76cQK0jqY4X0JTumpegJcByMIMR1Wf1g0eoOzpL7 9Bgo/NzvoB8GjBg8dZA0DB0avXk4xEDwFUjLXVaEIBjoskYKPwmwroQ453wKJsj2sj5c DewT5d2ukuDMhRgmdJi0kUG0yiM8xjs0J8Zhd+1BZp3nVaW19GB3xLtbEEFW0GDcYgAz 7BWg== 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=9dJ8ZbNRJip1W5R3juPd6Pbw/xeNyvq4XqNXo9NadZo=; b=jwDBMc+/dwdVDB5vpFAQlgAbGWti37Um7qfwLSCAG2FPG6pAoDgA7miEKZp9nnm8H/ qlul6buyfg4d7IbMQYcGt2HKeZtNTG5LHOcV1AmL6JgTFSegBn6NSfiu1Z+P+HdN78lj rvI9T2OYlsYSqIMbfCB6PKqWHYEne1iXcm/nFBymzcrpsddg82NBx0MbxF6VJseU1V5D AbocKK1GOm2XSbDbUTSXHHb92sDMxVE+77KcL20Yz54yLjPkXZKGG1MEVQ6F3Tegai09 cQuKZYGacb7bf+Ou7erTH9kgNswCc/+Hysg2msgJb1F1A2Am/lkuiEXe2aOAmbwnkF6o WByQ== X-Gm-Message-State: AKGB3mJApTXr2Eojwoob4i0vvFv0da9nHH50PAB9bc1RgkzhPIfgWJ/s H05AMVeEqRDUWKgUy7l0xNdFYgNi X-Google-Smtp-Source: ACJfBovNqt3nafJzMONJa2duMrvvPdWEFLH3BevY55SW0B4L5UXLFIR9JBFQhjRoWA9ECBiMulvd2Q== X-Received: by 10.98.13.133 with SMTP id 5mr14302555pfn.112.1513362506555; Fri, 15 Dec 2017 10:28:26 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:25 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks Date: Fri, 15 Dec 2017 10:27:57 -0800 Message-Id: <20171215182800.10248-4-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org To allocate the array of bucket locks for the hash table we now call library function alloc_bucket_spinlocks. Signed-off-by: Tom Herbert --- net/ipv6/ila/ila_xlat.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 887dd5b785b5..3ef8869ac508 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -31,26 +31,14 @@ struct ila_net { bool hooks_registered; }; +#define MAX_LOCKS 1024 #define LOCKS_PER_CPU 10 static int alloc_ila_locks(struct ila_net *ilan) { - unsigned int i, size; - unsigned int nr_pcpus = num_possible_cpus(); - - nr_pcpus = min_t(unsigned int, nr_pcpus, 32UL); - size = roundup_pow_of_two(nr_pcpus * LOCKS_PER_CPU); - - if (sizeof(spinlock_t) != 0) { - ilan->locks = kvmalloc(size * sizeof(spinlock_t), GFP_KERNEL); - if (!ilan->locks) - return -ENOMEM; - for (i = 0; i < size; i++) - spin_lock_init(&ilan->locks[i]); - } - ilan->locks_mask = size - 1; - - return 0; + return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask, + MAX_LOCKS, LOCKS_PER_CPU, + GFP_KERNEL); } static u32 hashrnd __read_mostly; @@ -639,7 +627,7 @@ static __net_exit void ila_exit_net(struct net *net) rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL); - kvfree(ilan->locks); + free_bucket_spinlocks(ilan->xlat.locks); if (ilan->hooks_registered) nf_unregister_net_hooks(net, ila_nf_hook_ops, From patchwork Fri Dec 15 18:27:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849354 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="bmY519uv"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzTM3cGvz9sBW for ; Sat, 16 Dec 2017 05:28:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756286AbdLOS2h (ORCPT ); Fri, 15 Dec 2017 13:28:37 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:46292 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755718AbdLOS23 (ORCPT ); Fri, 15 Dec 2017 13:28:29 -0500 Received: by mail-pg0-f67.google.com with SMTP id b11so6312946pgu.13 for ; Fri, 15 Dec 2017 10:28:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LyFAJmLD30yl+bttsrSStQ7iJXquVPLi8zVF3z2AJpQ=; b=bmY519uvCJXX89vHwSXRX+LpTmPuFIM/N7/2M8JH4mWtpd3JatNBVH3r5HCRlmT3P3 tQYMrubqTFGPMuQ+WbwR4ptlP+vfMr0LLWXliEWzf3RwF82ZA4c5tVoikjqXP91bNJnT 0iDiDKVviVG+HVgrLsfsc5pLrAV4fknPmno/G/apStNzlNquXrJWIl38HrOMchTjam+s wXvct8Ws21eNTCe8HhJdkffRQrg4ZpSbZ1icThXYinufkPAbn0BMYidnEeSp2bMwGsuY 30yGlTvzsk+ZoU/oG+AXe1eGpE2NpKeRDX3Lac3EtDCok76Tnmh/Z28b3SVfzrsz3yJ0 mykQ== 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=LyFAJmLD30yl+bttsrSStQ7iJXquVPLi8zVF3z2AJpQ=; b=rciHn0VqUSh7JhW07f++3UCXvNBHCHwNQEoubEApMEwaXfBmS7IBcqyXsY02fdFfJ8 hMa97ktl7wfMd0M+CR/R/Y6gb2fNRcZYqHpX1E4mT5/4ckvVEc0aEsq0EcqWcYDXOYAe qan+jTygcsm1vBR70aJFIMb7qrZUgTXKiP3Boo5313TszXyy0q1XoSAAwek8fTMV4HIX suLCCU3bfdZBqkpWFUoCmN4V4gXjnVvt83EdBsBv3xHLjJg/wjpXDoradI4mqRDqq9/M ZtQ1pnbI9DqZpDQqmqxe473SbTd71UIOTCG+j24oCBeMcaA4U9kH+onehUoaWEN5kEfj p5iA== X-Gm-Message-State: AKGB3mJdzpfVBoWJ2WS4rYFpzMdl/K0uobLK0/BycdwaaZpdH3Z/nHYj ZKIH8sHvYX6yoOisUcHqMHsXBw== X-Google-Smtp-Source: ACJfBoukrzfg2ALvYPxrkD1JNxoXfGwVNDWhjUM5XaX/CG1hml28P2d/CACPGS2MeVYL+GYrh4aJWw== X-Received: by 10.99.65.135 with SMTP id o129mr12716755pga.81.1513362509155; Fri, 15 Dec 2017 10:28:29 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:27 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 4/6] ila: create main ila source file Date: Fri, 15 Dec 2017 10:27:58 -0800 Message-Id: <20171215182800.10248-5-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Create a main ila file that contains the module initialization functions as well as netlink definitions. Previously these were defined in ila_xlat and ila_common. This approach allows better extensibility. Signed-off-by: Tom Herbert --- net/ipv6/ila/Makefile | 2 +- net/ipv6/ila/ila.h | 26 ++++++++- net/ipv6/ila/ila_common.c | 30 ---------- net/ipv6/ila/ila_main.c | 115 ++++++++++++++++++++++++++++++++++++++ net/ipv6/ila/ila_xlat.c | 138 +++++++++------------------------------------- 5 files changed, 166 insertions(+), 145 deletions(-) create mode 100644 net/ipv6/ila/ila_main.c diff --git a/net/ipv6/ila/Makefile b/net/ipv6/ila/Makefile index 4b32e5921e5c..b7739aba6e68 100644 --- a/net/ipv6/ila/Makefile +++ b/net/ipv6/ila/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_IPV6_ILA) += ila.o -ila-objs := ila_common.o ila_lwt.o ila_xlat.o +ila-objs := ila_main.o ila_common.o ila_lwt.o ila_xlat.o diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h index 3c7a11b62334..faba7824ea56 100644 --- a/net/ipv6/ila/ila.h +++ b/net/ipv6/ila/ila.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -104,9 +105,30 @@ void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p, void ila_init_saved_csum(struct ila_params *p); +struct ila_net { + struct { + struct rhashtable rhash_table; + spinlock_t *locks; /* Bucket locks for entry manipulation */ + unsigned int locks_mask; + bool hooks_registered; + } xlat; +}; + int ila_lwt_init(void); void ila_lwt_fini(void); -int ila_xlat_init(void); -void ila_xlat_fini(void); + +int ila_xlat_init_net(struct net *net); +void ila_xlat_exit_net(struct net *net); + +int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info); +int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info); +int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info); +int ila_xlat_nl_dump_start(struct netlink_callback *cb); +int ila_xlat_nl_dump_done(struct netlink_callback *cb); +int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb); + +extern unsigned int ila_net_id; + +extern struct genl_family ila_nl_family; #endif /* __ILA_H */ diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c index 8c88ecf29b93..579310466eac 100644 --- a/net/ipv6/ila/ila_common.c +++ b/net/ipv6/ila/ila_common.c @@ -154,33 +154,3 @@ void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p, iaddr->loc = p->locator; } -static int __init ila_init(void) -{ - int ret; - - ret = ila_lwt_init(); - - if (ret) - goto fail_lwt; - - ret = ila_xlat_init(); - if (ret) - goto fail_xlat; - - return 0; -fail_xlat: - ila_lwt_fini(); -fail_lwt: - return ret; -} - -static void __exit ila_fini(void) -{ - ila_xlat_fini(); - ila_lwt_fini(); -} - -module_init(ila_init); -module_exit(ila_fini); -MODULE_AUTHOR("Tom Herbert "); -MODULE_LICENSE("GPL"); diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c new file mode 100644 index 000000000000..f6ac6b14577e --- /dev/null +++ b/net/ipv6/ila/ila_main.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include "ila.h" + +static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { + [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, + [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, }, + [ILA_ATTR_IFINDEX] = { .type = NLA_U32, }, + [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, + [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, +}; + +static const struct genl_ops ila_nl_ops[] = { + { + .cmd = ILA_CMD_ADD, + .doit = ila_xlat_nl_cmd_add_mapping, + .policy = ila_nl_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = ILA_CMD_DEL, + .doit = ila_xlat_nl_cmd_del_mapping, + .policy = ila_nl_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = ILA_CMD_GET, + .doit = ila_xlat_nl_cmd_get_mapping, + .start = ila_xlat_nl_dump_start, + .dumpit = ila_xlat_nl_dump, + .done = ila_xlat_nl_dump_done, + .policy = ila_nl_policy, + }, +}; + +unsigned int ila_net_id; + +struct genl_family ila_nl_family __ro_after_init = { + .hdrsize = 0, + .name = ILA_GENL_NAME, + .version = ILA_GENL_VERSION, + .maxattr = ILA_ATTR_MAX, + .netnsok = true, + .parallel_ops = true, + .module = THIS_MODULE, + .ops = ila_nl_ops, + .n_ops = ARRAY_SIZE(ila_nl_ops), +}; + +static __net_init int ila_init_net(struct net *net) +{ + int err; + + err = ila_xlat_init_net(net); + if (err) + goto ila_xlat_init_fail; + + return 0; + +ila_xlat_init_fail: + return err; +} + +static __net_exit void ila_exit_net(struct net *net) +{ + ila_xlat_exit_net(net); +} + +static struct pernet_operations ila_net_ops = { + .init = ila_init_net, + .exit = ila_exit_net, + .id = &ila_net_id, + .size = sizeof(struct ila_net), +}; + +static int __init ila_init(void) +{ + int ret; + + ret = register_pernet_device(&ila_net_ops); + if (ret) + goto register_device_fail; + + ret = genl_register_family(&ila_nl_family); + if (ret) + goto register_family_fail; + + ret = ila_lwt_init(); + if (ret) + goto fail_lwt; + + return 0; + +fail_lwt: + genl_unregister_family(&ila_nl_family); +register_family_fail: + unregister_pernet_device(&ila_net_ops); +register_device_fail: + return ret; +} + +static void __exit ila_fini(void) +{ + ila_lwt_fini(); + genl_unregister_family(&ila_nl_family); + unregister_pernet_device(&ila_net_ops); +} + +module_init(ila_init); +module_exit(ila_fini); +MODULE_AUTHOR("Tom Herbert "); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 3ef8869ac508..d05de891dfb6 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -22,15 +22,6 @@ struct ila_map { struct rcu_head rcu; }; -static unsigned int ila_net_id; - -struct ila_net { - struct rhashtable rhash_table; - spinlock_t *locks; /* Bucket locks for entry manipulation */ - unsigned int locks_mask; - bool hooks_registered; -}; - #define MAX_LOCKS 1024 #define LOCKS_PER_CPU 10 @@ -58,7 +49,7 @@ static inline u32 ila_locator_hash(struct ila_locator loc) static inline spinlock_t *ila_get_lock(struct ila_net *ilan, struct ila_locator loc) { - return &ilan->locks[ila_locator_hash(loc) & ilan->locks_mask]; + return &ilan->xlat.locks[ila_locator_hash(loc) & ilan->xlat.locks_mask]; } static inline int ila_cmp_wildcards(struct ila_map *ila, @@ -102,16 +93,6 @@ static const struct rhashtable_params rht_params = { .obj_cmpfn = ila_cmpfn, }; -static struct genl_family ila_nl_family; - -static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { - [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, - [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, }, - [ILA_ATTR_IFINDEX] = { .type = NLA_U32, }, - [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, - [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, -}; - static int parse_nl_config(struct genl_info *info, struct ila_xlat_params *xp) { @@ -149,7 +130,7 @@ static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr, { struct ila_map *ila; - ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->loc, + ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &iaddr->loc, rht_params); while (ila) { if (!ila_cmp_wildcards(ila, iaddr, ifindex)) @@ -166,7 +147,7 @@ static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *xp, { struct ila_map *ila; - ila = rhashtable_lookup_fast(&ilan->rhash_table, + ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &xp->ip.locator_match, rht_params); while (ila) { @@ -222,7 +203,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match); int err = 0, order; - if (!ilan->hooks_registered) { + if (!ilan->xlat.hooks_registered) { /* We defer registering net hooks in the namespace until the * first mapping is added. */ @@ -231,7 +212,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) if (err) return err; - ilan->hooks_registered = true; + ilan->xlat.hooks_registered = true; } ila = kzalloc(sizeof(*ila), GFP_KERNEL); @@ -246,12 +227,12 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) spin_lock(lock); - head = rhashtable_lookup_fast(&ilan->rhash_table, + head = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &xp->ip.locator_match, rht_params); if (!head) { /* New entry for the rhash_table */ - err = rhashtable_lookup_insert_fast(&ilan->rhash_table, + err = rhashtable_lookup_insert_fast(&ilan->xlat.rhash_table, &ila->node, rht_params); } else { struct ila_map *tila = head, *prev = NULL; @@ -277,7 +258,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) } else { /* Make this ila new head */ RCU_INIT_POINTER(ila->next, head); - err = rhashtable_replace_fast(&ilan->rhash_table, + err = rhashtable_replace_fast(&ilan->xlat.rhash_table, &head->node, &ila->node, rht_params); if (err) @@ -303,7 +284,7 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp) spin_lock(lock); - head = rhashtable_lookup_fast(&ilan->rhash_table, + head = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &xp->ip.locator_match, rht_params); ila = head; @@ -333,15 +314,15 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp) * table */ err = rhashtable_replace_fast( - &ilan->rhash_table, &ila->node, + &ilan->xlat.rhash_table, &ila->node, &head->node, rht_params); if (err) goto out; } else { /* Entry no longer used */ - err = rhashtable_remove_fast(&ilan->rhash_table, - &ila->node, - rht_params); + err = rhashtable_remove_fast( + &ilan->xlat.rhash_table, + &ila->node, rht_params); } } @@ -356,7 +337,7 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp) return err; } -static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info) +int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info) { struct net *net = genl_info_net(info); struct ila_xlat_params p; @@ -369,7 +350,7 @@ static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info) return ila_add_mapping(net, &p); } -static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info) +int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info) { struct net *net = genl_info_net(info); struct ila_xlat_params xp; @@ -421,7 +402,7 @@ static int ila_dump_info(struct ila_map *ila, return -EMSGSIZE; } -static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info) +int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info) { struct net *net = genl_info_net(info); struct ila_net *ilan = net_generic(net, ila_net_id); @@ -465,7 +446,7 @@ struct ila_dump_iter { int skip; }; -static int ila_nl_dump_start(struct netlink_callback *cb) +int ila_xlat_nl_dump_start(struct netlink_callback *cb) { struct net *net = sock_net(cb->skb->sk); struct ila_net *ilan = net_generic(net, ila_net_id); @@ -476,7 +457,7 @@ static int ila_nl_dump_start(struct netlink_callback *cb) if (!iter) return -ENOMEM; - ret = rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter, + ret = rhashtable_walk_init(&ilan->xlat.rhash_table, &iter->rhiter, GFP_KERNEL); if (ret) { kfree(iter); @@ -489,7 +470,7 @@ static int ila_nl_dump_start(struct netlink_callback *cb) return ret; } -static int ila_nl_dump_done(struct netlink_callback *cb) +int ila_xlat_nl_dump_done(struct netlink_callback *cb) { struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0]; @@ -500,7 +481,7 @@ static int ila_nl_dump_done(struct netlink_callback *cb) return 0; } -static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb) +int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0]; struct rhashtable_iter *rhiter = &iter->rhiter; @@ -570,77 +551,35 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb) return ret; } -static const struct genl_ops ila_nl_ops[] = { - { - .cmd = ILA_CMD_ADD, - .doit = ila_nl_cmd_add_mapping, - .policy = ila_nl_policy, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = ILA_CMD_DEL, - .doit = ila_nl_cmd_del_mapping, - .policy = ila_nl_policy, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = ILA_CMD_GET, - .doit = ila_nl_cmd_get_mapping, - .start = ila_nl_dump_start, - .dumpit = ila_nl_dump, - .done = ila_nl_dump_done, - .policy = ila_nl_policy, - }, -}; - -static struct genl_family ila_nl_family __ro_after_init = { - .hdrsize = 0, - .name = ILA_GENL_NAME, - .version = ILA_GENL_VERSION, - .maxattr = ILA_ATTR_MAX, - .netnsok = true, - .parallel_ops = true, - .module = THIS_MODULE, - .ops = ila_nl_ops, - .n_ops = ARRAY_SIZE(ila_nl_ops), -}; - #define ILA_HASH_TABLE_SIZE 1024 -static __net_init int ila_init_net(struct net *net) +int ila_xlat_init_net(struct net *net) { - int err; struct ila_net *ilan = net_generic(net, ila_net_id); + int err; err = alloc_ila_locks(ilan); if (err) return err; - rhashtable_init(&ilan->rhash_table, &rht_params); + rhashtable_init(&ilan->xlat.rhash_table, &rht_params); return 0; } -static __net_exit void ila_exit_net(struct net *net) +void ila_xlat_exit_net(struct net *net) { struct ila_net *ilan = net_generic(net, ila_net_id); - rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL); + rhashtable_free_and_destroy(&ilan->xlat.rhash_table, ila_free_cb, NULL); free_bucket_spinlocks(ilan->xlat.locks); - if (ilan->hooks_registered) + if (ilan->xlat.hooks_registered) nf_unregister_net_hooks(net, ila_nf_hook_ops, ARRAY_SIZE(ila_nf_hook_ops)); } -static struct pernet_operations ila_net_ops = { - .init = ila_init_net, - .exit = ila_exit_net, - .id = &ila_net_id, - .size = sizeof(struct ila_net), -}; - static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila) { struct ila_map *ila; @@ -667,28 +606,3 @@ static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila) return 0; } -int __init ila_xlat_init(void) -{ - int ret; - - ret = register_pernet_device(&ila_net_ops); - if (ret) - goto exit; - - ret = genl_register_family(&ila_nl_family); - if (ret < 0) - goto unregister; - - return 0; - -unregister: - unregister_pernet_device(&ila_net_ops); -exit: - return ret; -} - -void ila_xlat_fini(void) -{ - genl_unregister_family(&ila_nl_family); - unregister_pernet_device(&ila_net_ops); -} From patchwork Fri Dec 15 18:27:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849356 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="CisAW/WI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzTX1Xr9z9sBW for ; Sat, 16 Dec 2017 05:28:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756320AbdLOS2p (ORCPT ); Fri, 15 Dec 2017 13:28:45 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:37383 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755561AbdLOS2c (ORCPT ); Fri, 15 Dec 2017 13:28:32 -0500 Received: by mail-pf0-f195.google.com with SMTP id n6so6713763pfa.4 for ; Fri, 15 Dec 2017 10:28:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=X7Ovj+WOvHsAQCxHLmWX6FS4WucxSB1gEoHcs4Rqpqk=; b=CisAW/WIk7K6bUfIo0+Gw5qPPjek+a/U/aCepFXl7wcbq9kBHD3hiWFLuHzRTd5iBo qUYmYJwaWYgf7dhMxKRKYvzhFu6l2XvpqJ55VOV+TH53wEHm7RIC4ER83cql91wvXRbI cia43z8MWrFLTthAZa27g1N5hvJCJTUHB52ZNB0OptcTIOE3MROUu2AKRL3cERf3R4Mw j5mEvoZg0hSz1rWuWoHewoA3Vc4g7FxNepJ+PMMf26ZPnK4Kq9sWdBgJvfY8kpilRMvo XCBoXpCUcoeU7QLwd/zUERD77SEZm+QDJ4bU2dTJ8kN8GumPUPdF95nivmYGBOZu7euT ckeQ== 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=X7Ovj+WOvHsAQCxHLmWX6FS4WucxSB1gEoHcs4Rqpqk=; b=t5XN2ZZKHmq8hqaZ8IPDvcuI2fbsqaqxLIabY5c2led85ZNNgKxdN6Mz+MlQ7Lcvll 730adEVSEyz5l/jyW6n1TrFqyPMyMPsJu1QH8cL7k288lgn5An4/xHjPj86FCjA0nucE bObeI5V0wlBiu/duXkslwu/pcXEzBhl93Sl3kj783YaAE61wfwdvnIze5H25NOb1RHjP yvBQbA7BoRhKuBnA/r+uno3TnDDh8Uq4wYPER5EL6e98+g+wvx90UgpbByEc8nAXMkw5 82gFRBBB+FoBLy9Ld7gEL+g4yXuWf6Cg3dFyolSe+5ALYHXfDpjlgA3QF+mQ/dHF1FM3 YYUw== X-Gm-Message-State: AKGB3mIbWmWCHZ+rs8hLP/p4ORDmRAl5l6IEo9BCY7DpSHlqcN4hr60r VbyRmFgSy6yJ86twvNfAyvTKlg== X-Google-Smtp-Source: ACJfBouuSMe4myhTBAqImJAGwqQVyugzM7YsshUYosCywvgo0qYDo3OTalhtYEPJGPpKdeZdmfLzFQ== X-Received: by 10.101.88.201 with SMTP id e9mr12841311pgu.216.1513362511444; Fri, 15 Dec 2017 10:28:31 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:30 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 5/6] ila: Flush netlink command to clear xlat table Date: Fri, 15 Dec 2017 10:27:59 -0800 Message-Id: <20171215182800.10248-6-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add ILA_CMD_FLUSH netlink command to clear the ILA translation table. Signed-off-by: Tom Herbert --- include/uapi/linux/ila.h | 1 + net/ipv6/ila/ila.h | 1 + net/ipv6/ila/ila_main.c | 6 +++++ net/ipv6/ila/ila_xlat.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h index 483b77af4eb8..db45d3e49a12 100644 --- a/include/uapi/linux/ila.h +++ b/include/uapi/linux/ila.h @@ -30,6 +30,7 @@ enum { ILA_CMD_ADD, ILA_CMD_DEL, ILA_CMD_GET, + ILA_CMD_FLUSH, __ILA_CMD_MAX, }; diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h index faba7824ea56..1f747bcbec29 100644 --- a/net/ipv6/ila/ila.h +++ b/net/ipv6/ila/ila.h @@ -123,6 +123,7 @@ void ila_xlat_exit_net(struct net *net); int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info); int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info); int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info); +int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info); int ila_xlat_nl_dump_start(struct netlink_callback *cb); int ila_xlat_nl_dump_done(struct netlink_callback *cb); int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb); diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c index f6ac6b14577e..18fac76b9520 100644 --- a/net/ipv6/ila/ila_main.c +++ b/net/ipv6/ila/ila_main.c @@ -27,6 +27,12 @@ static const struct genl_ops ila_nl_ops[] = { .flags = GENL_ADMIN_PERM, }, { + .cmd = ILA_CMD_FLUSH, + .doit = ila_xlat_nl_cmd_flush, + .policy = ila_nl_policy, + .flags = GENL_ADMIN_PERM, + }, + { .cmd = ILA_CMD_GET, .doit = ila_xlat_nl_cmd_get_mapping, .start = ila_xlat_nl_dump_start, diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index d05de891dfb6..51a15ce50a64 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -164,9 +164,9 @@ static inline void ila_release(struct ila_map *ila) kfree_rcu(ila, rcu); } -static void ila_free_cb(void *ptr, void *arg) +static void ila_free_node(struct ila_map *ila) { - struct ila_map *ila = (struct ila_map *)ptr, *next; + struct ila_map *next; /* Assume rcu_readlock held */ while (ila) { @@ -176,6 +176,11 @@ static void ila_free_cb(void *ptr, void *arg) } } +static void ila_free_cb(void *ptr, void *arg) +{ + ila_free_node((struct ila_map *)ptr); +} + static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila); static unsigned int @@ -365,6 +370,59 @@ int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info) return 0; } +static inline spinlock_t *lock_from_ila_map(struct ila_net *ilan, + struct ila_map *ila) +{ + return ila_get_lock(ilan, ila->xp.ip.locator_match); +} + +int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info) +{ + struct net *net = genl_info_net(info); + struct ila_net *ilan = net_generic(net, ila_net_id); + struct rhashtable_iter iter; + struct ila_map *ila; + spinlock_t *lock; + int ret; + + ret = rhashtable_walk_init(&ilan->xlat.rhash_table, &iter, GFP_KERNEL); + if (ret) + goto done; + + rhashtable_walk_start(&iter); + + for (;;) { + ila = rhashtable_walk_next(&iter); + + if (IS_ERR(ila)) { + if (PTR_ERR(ila) == -EAGAIN) + continue; + ret = PTR_ERR(ila); + goto done; + } else if (!ila) { + break; + } + + lock = lock_from_ila_map(ilan, ila); + + spin_lock(lock); + + ret = rhashtable_remove_fast(&ilan->xlat.rhash_table, + &ila->node, rht_params); + if (!ret) + ila_free_node(ila); + + spin_unlock(lock); + + if (ret) + break; + } + +done: + rhashtable_walk_stop(&iter); + return ret; +} + static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg) { if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR, From patchwork Fri Dec 15 18:28:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 849355 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="DB52iKXm"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yyzTS5gkTz9sBW for ; Sat, 16 Dec 2017 05:28:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756296AbdLOS2n (ORCPT ); Fri, 15 Dec 2017 13:28:43 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:42220 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756144AbdLOS2f (ORCPT ); Fri, 15 Dec 2017 13:28:35 -0500 Received: by mail-pf0-f196.google.com with SMTP id d23so6700764pfe.9 for ; Fri, 15 Dec 2017 10:28:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PyzpvwDRZNgUYYf1sPwod8/m/PulMyCEUy8VGU8l6+o=; b=DB52iKXmurtPhLl3RUG0JYgQ96BxDn415O8PHwRpdJRQ+TEK1tKldAiuiWmWuNIZLV s+KtvPHu58yq+6KnX14ZzwCCQv7INlE8bgSO71hFDI1xScvHl4vTNWe1mqebUVWtGsw5 s3wtfdVgbF/aAKv0ikAQtioMnIrjJxF+WmIoaMm8Jem52n3fXoXAlsXkOvKZKiZ58n7Z Fx/CRMV93M7nyzabCZVNNBuDUdpus/Kt153FNq+tKUlNrJgOZmWAA1y8m6XvXfrAAPuE UjPFYArBWyKgJRGm7qFmgBpTDKSrWLNdVwaDE4plMghJ8XaeSXAYZViWeRGNPGf2ybEw kSaQ== 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=PyzpvwDRZNgUYYf1sPwod8/m/PulMyCEUy8VGU8l6+o=; b=mhGqGujYkUf9L0k/2H12zNG6aw4Fp2WNU/MPTHCBiwG1kqcj3WEBTUUAbOelI4RqVq d2Mvc3GLcXx3RK2q3A0xtLB7lEf68++/39ABHUdzAS5BdxmLJu2/KK9luygt+10jzYxw zpH7MNnX1l3J9V6LUWaAXtjqxKQX6hfIObd5NWPo1DHCSHsDyIfdq2BqHE4faOw/IRLZ u3s3zxIZChMrLDfzhn9rYIAUJEMWCvwx6VDgVnU8k2dgRgsTdOB4BYsEkKiTj9FhvA0m gvSve1WAmOrS07xywZSgkmZAg1XVfkLE50lENJHpT/2Ok6wq42EPdkiRmCKUM0XrUiZA CPUg== X-Gm-Message-State: AKGB3mIMNG3JX6T5cccBwTqKumXOtU0giH2rM1/GVzYQnpKkpKbuBmRi Qe144OGOhvVKXCB3EUvlV7pWwg== X-Google-Smtp-Source: ACJfBov5wwh352oVxBf1MciY4nzoih28GcgZ9vnPFhFmT1ppJqqUZGa6z+oHPAAi3uLL3vJ+1gmVmA== X-Received: by 10.98.7.27 with SMTP id b27mr14264245pfd.240.1513362514229; Fri, 15 Dec 2017 10:28:34 -0800 (PST) Received: from localhost.localdomain (67-207-98-108.static.wiline.com. [67.207.98.108]) by smtp.gmail.com with ESMTPSA id 69sm14120903pfj.28.2017.12.15.10.28.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Dec 2017 10:28:33 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, roopa@cumulusnetworks.com, rohit@quantonium.net, Tom Herbert Subject: [PATCH v4 net-next 6/6] ila: Route notify Date: Fri, 15 Dec 2017 10:28:00 -0800 Message-Id: <20171215182800.10248-7-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171215182800.10248-1-tom@quantonium.net> References: <20171215182800.10248-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement RTM notifications for ILA routers. This adds support to ILA LWT to send a netlink RTM message when a router is uses. THe ILA notify mechanism can be used in two contexts: - On an ILA forwarding cache a route prefix can be configured to do an ILA notification. This method is used when address resolution needs to be done on an address. - One an ILA router an ILA host route entry may include a noitification. The purpose of this is to get a notification to a userspace daemon to send and ILA redirect Signed-off-by: Tom Herbert --- include/uapi/linux/ila.h | 2 + include/uapi/linux/rtnetlink.h | 8 +- net/ipv6/ila/ila_lwt.c | 268 ++++++++++++++++++++++++++++------------- 3 files changed, 193 insertions(+), 85 deletions(-) diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h index db45d3e49a12..5675f3e71fac 100644 --- a/include/uapi/linux/ila.h +++ b/include/uapi/linux/ila.h @@ -19,6 +19,8 @@ enum { ILA_ATTR_CSUM_MODE, /* u8 */ ILA_ATTR_IDENT_TYPE, /* u8 */ ILA_ATTR_HOOK_TYPE, /* u8 */ + ILA_ATTR_NOTIFY_DST, /* flag */ + ILA_ATTR_NOTIFY_SRC, /* flag */ __ILA_ATTR_MAX, }; diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index d8b5f80c2ea6..8d358a300d8a 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -13,7 +13,8 @@ */ #define RTNL_FAMILY_IPMR 128 #define RTNL_FAMILY_IP6MR 129 -#define RTNL_FAMILY_MAX 129 +#define RTNL_FAMILY_ILA 130 +#define RTNL_FAMILY_MAX 130 /**** * Routing/neighbour discovery messages. @@ -150,6 +151,9 @@ enum { RTM_NEWCACHEREPORT = 96, #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT + RTM_ADDR_RESOLVE = 98, +#define RTM_ADDR_RESOLVE RTM_ADDR_RESOLVE + __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; @@ -676,6 +680,8 @@ enum rtnetlink_groups { #define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV6_MROUTE_R, #define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R + RTNLGRP_ILA_NOTIFY, +#define RTNLGRP_ILA_NOTIFY RTNLGRP_ILA_NOTIFY __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c index 9f1e46a1468e..303c91e3bf76 100644 --- a/net/ipv6/ila/ila_lwt.c +++ b/net/ipv6/ila/ila_lwt.c @@ -19,10 +19,15 @@ struct ila_lwt { struct ila_params p; struct dst_cache dst_cache; + u8 hook_type; u32 connected : 1; - u32 lwt_output : 1; + u32 xlat : 1; + u32 notify : 2; }; +#define ILA_NOTIFY_DST 1 +#define ILA_NOTIFY_SRC 2 + static inline struct ila_lwt *ila_lwt_lwtunnel( struct lwtunnel_state *lwt) { @@ -35,6 +40,67 @@ static inline struct ila_params *ila_params_lwtunnel( return &ila_lwt_lwtunnel(lwt)->p; } +static size_t ila_rslv_msgsize(void) +{ + size_t len = + NLMSG_ALIGN(sizeof(struct rtmsg)) + + nla_total_size(16) /* RTA_DST */ + + nla_total_size(16) /* RTA_SRC */ + ; + + return len; +} + +void ila_notify(struct net *net, struct sk_buff *skb, struct ila_lwt *lwt) +{ + struct ipv6hdr *ip6h = ipv6_hdr(skb); + int flags = NLM_F_MULTI; + struct sk_buff *nlskb; + struct nlmsghdr *nlh; + struct rtmsg *rtm; + int err = 0; + + /* Send ILA notification to user */ + nlskb = nlmsg_new(ila_rslv_msgsize(), GFP_KERNEL); + if (!nlskb) + return; + + nlh = nlmsg_put(nlskb, 0, 0, RTM_ADDR_RESOLVE, sizeof(*rtm), flags); + if (!nlh) { + err = -EMSGSIZE; + goto errout; + } + + rtm = nlmsg_data(nlh); + rtm->rtm_family = AF_INET6; + rtm->rtm_dst_len = 128; + rtm->rtm_src_len = 0; + rtm->rtm_tos = 0; + rtm->rtm_table = RT6_TABLE_UNSPEC; + rtm->rtm_type = RTN_UNICAST; + rtm->rtm_scope = RT_SCOPE_UNIVERSE; + + if (((lwt->notify & ILA_NOTIFY_DST) && + nla_put_in6_addr(nlskb, RTA_DST, &ip6h->daddr)) || + ((lwt->notify & ILA_NOTIFY_SRC) && + nla_put_in6_addr(nlskb, RTA_SRC, &ip6h->saddr))) { + nlmsg_cancel(nlskb, nlh); + err = -EMSGSIZE; + goto errout; + } + + nlmsg_end(nlskb, nlh); + + rtnl_notify(nlskb, net, 0, RTNLGRP_ILA_NOTIFY, NULL, GFP_ATOMIC); + + return; + +errout: + kfree_skb(nlskb); + WARN_ON(err == -EMSGSIZE); + rtnl_set_sk_err(net, RTNLGRP_ILA_NOTIFY, err); +} + static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb) { struct dst_entry *orig_dst = skb_dst(skb); @@ -46,11 +112,14 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb) if (skb->protocol != htons(ETH_P_IPV6)) goto drop; - if (ilwt->lwt_output) + if (ilwt->xlat) ila_update_ipv6_locator(skb, ila_params_lwtunnel(orig_dst->lwtstate), true); + if (ilwt->notify) + ila_notify(net, skb, ilwt); + if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) { /* Already have a next hop address in route, no need for * dest cache route. @@ -106,11 +175,14 @@ static int ila_input(struct sk_buff *skb) if (skb->protocol != htons(ETH_P_IPV6)) goto drop; - if (!ilwt->lwt_output) + if (ilwt->xlat) ila_update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate), false); + if (ilwt->notify) + ila_notify(dev_net(dst->dev), skb, ilwt); + return dst->lwtstate->orig_input(skb); drop: @@ -123,6 +195,8 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, [ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, }, + [ILA_ATTR_NOTIFY_DST] = { .type = NLA_FLAG }, + [ILA_ATTR_NOTIFY_SRC] = { .type = NLA_FLAG }, }; static int ila_build_state(struct net *net, struct nlattr *nla, @@ -130,64 +204,73 @@ static int ila_build_state(struct net *net, struct nlattr *nla, struct lwtunnel_state **ts, struct netlink_ext_ack *extack) { - struct ila_lwt *ilwt; - struct ila_params *p; - struct nlattr *tb[ILA_ATTR_MAX + 1]; - struct lwtunnel_state *newts; const struct fib6_config *cfg6 = cfg; - struct ila_addr *iaddr; + struct ila_addr *iaddr = (struct ila_addr *)&cfg6->fc_dst; u8 ident_type = ILA_ATYPE_USE_FORMAT; u8 hook_type = ILA_HOOK_ROUTE_OUTPUT; + struct nlattr *tb[ILA_ATTR_MAX + 1]; u8 csum_mode = ILA_CSUM_NO_ACTION; - bool lwt_output = true; + struct lwtunnel_state *newts; + struct ila_lwt *ilwt; + struct ila_params *p; u8 eff_ident_type; - int ret; + int err; if (family != AF_INET6) return -EINVAL; - ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack); - if (ret < 0) - return ret; + err = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack); + if (err < 0) + return err; - if (!tb[ILA_ATTR_LOCATOR]) - return -EINVAL; + if (tb[ILA_ATTR_LOCATOR]) { + /* Doing ILA translation */ - iaddr = (struct ila_addr *)&cfg6->fc_dst; + if (tb[ILA_ATTR_IDENT_TYPE]) + ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]); - if (tb[ILA_ATTR_IDENT_TYPE]) - ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]); + if (ident_type == ILA_ATYPE_USE_FORMAT) { + /* Infer identifier type from type field in formatted + * identifier. + */ - if (ident_type == ILA_ATYPE_USE_FORMAT) { - /* Infer identifier type from type field in formatted - * identifier. - */ + if (cfg6->fc_dst_len < 8 * + sizeof(struct ila_locator) + 3) { + /* Need to have full locator and at least type + * field included in destination + */ + return -EINVAL; + } + + eff_ident_type = iaddr->ident.type; + } else { + eff_ident_type = ident_type; + } - if (cfg6->fc_dst_len < 8 * sizeof(struct ila_locator) + 3) { - /* Need to have full locator and at least type field - * included in destination - */ + switch (eff_ident_type) { + case ILA_ATYPE_IID: + /* Don't allow ILA for IID type */ + return -EINVAL; + case ILA_ATYPE_LUID: + break; + case ILA_ATYPE_VIRT_V4: + case ILA_ATYPE_VIRT_UNI_V6: + case ILA_ATYPE_VIRT_MULTI_V6: + case ILA_ATYPE_NONLOCAL_ADDR: + /* These ILA formats are not supported yet. */ + default: return -EINVAL; } - eff_ident_type = iaddr->ident.type; - } else { - eff_ident_type = ident_type; - } + csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]); - switch (eff_ident_type) { - case ILA_ATYPE_IID: - /* Don't allow ILA for IID type */ - return -EINVAL; - case ILA_ATYPE_LUID: - break; - case ILA_ATYPE_VIRT_V4: - case ILA_ATYPE_VIRT_UNI_V6: - case ILA_ATYPE_VIRT_MULTI_V6: - case ILA_ATYPE_NONLOCAL_ADDR: - /* These ILA formats are not supported yet. */ - default: - return -EINVAL; + if (csum_mode == ILA_CSUM_NEUTRAL_MAP && + ila_csum_neutral_set(iaddr->ident)) { + /* Don't allow translation if checksum neutral bit is + * configured and it's set in the SIR address. + */ + return -EINVAL; + } } if (tb[ILA_ATTR_HOOK_TYPE]) @@ -195,58 +278,62 @@ static int ila_build_state(struct net *net, struct nlattr *nla, switch (hook_type) { case ILA_HOOK_ROUTE_OUTPUT: - lwt_output = true; - break; case ILA_HOOK_ROUTE_INPUT: - lwt_output = false; break; default: return -EINVAL; } - if (tb[ILA_ATTR_CSUM_MODE]) - csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]); - - if (csum_mode == ILA_CSUM_NEUTRAL_MAP && - ila_csum_neutral_set(iaddr->ident)) { - /* Don't allow translation if checksum neutral bit is - * configured and it's set in the SIR address. - */ - return -EINVAL; - } - newts = lwtunnel_state_alloc(sizeof(*ilwt)); if (!newts) return -ENOMEM; ilwt = ila_lwt_lwtunnel(newts); - ret = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC); - if (ret) { + + err = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC); + if (err) { kfree(newts); - return ret; + return err; } - ilwt->lwt_output = !!lwt_output; + newts->type = LWTUNNEL_ENCAP_ILA; - p = ila_params_lwtunnel(newts); + switch (hook_type) { + case ILA_HOOK_ROUTE_OUTPUT: + newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT; + break; + case ILA_HOOK_ROUTE_INPUT: + newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT; + break; + } - p->csum_mode = csum_mode; - p->ident_type = ident_type; - p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]); + ilwt->hook_type = hook_type; - /* Precompute checksum difference for translation since we - * know both the old locator and the new one. - */ - p->locator_match = iaddr->loc; + if (tb[ILA_ATTR_NOTIFY_DST]) + ilwt->notify |= ILA_NOTIFY_DST; - ila_init_saved_csum(p); + if (tb[ILA_ATTR_NOTIFY_SRC]) + ilwt->notify |= ILA_NOTIFY_SRC; - newts->type = LWTUNNEL_ENCAP_ILA; - newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT | - LWTUNNEL_STATE_INPUT_REDIRECT; + p = ila_params_lwtunnel(newts); - if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr)) - ilwt->connected = 1; + if (tb[ILA_ATTR_LOCATOR]) { + ilwt->xlat = true; + p->csum_mode = csum_mode; + p->ident_type = ident_type; + p->locator.v64 = (__force __be64)nla_get_u64( + tb[ILA_ATTR_LOCATOR]); + + /* Precompute checksum difference for translation since we + * know both the old locator and the new one. + */ + p->locator_match = iaddr->loc; + + ila_init_saved_csum(p); + + if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr)) + ilwt->connected = 1; + } *ts = newts; @@ -264,21 +351,32 @@ static int ila_fill_encap_info(struct sk_buff *skb, struct ila_params *p = ila_params_lwtunnel(lwtstate); struct ila_lwt *ilwt = ila_lwt_lwtunnel(lwtstate); - if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64, - ILA_ATTR_PAD)) + if (ilwt->xlat) { + if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, + (__force u64)p->locator.v64, + ILA_ATTR_PAD)) goto nla_put_failure; - if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE, (__force u8)p->csum_mode)) - goto nla_put_failure; + if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE, + (__force u8)p->csum_mode)) + goto nla_put_failure; - if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type)) - goto nla_put_failure; + if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, + (__force u8)p->ident_type)) + goto nla_put_failure; + } - if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE, - ilwt->lwt_output ? ILA_HOOK_ROUTE_OUTPUT : - ILA_HOOK_ROUTE_INPUT)) + if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE, ilwt->hook_type)) goto nla_put_failure; + if (ilwt->notify & ILA_NOTIFY_DST) + if (nla_put_flag(skb, ILA_ATTR_NOTIFY_DST)) + goto nla_put_failure; + + if (ilwt->notify & ILA_NOTIFY_SRC) + if (nla_put_flag(skb, ILA_ATTR_NOTIFY_SRC)) + goto nla_put_failure; + return 0; nla_put_failure: @@ -291,6 +389,8 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) nla_total_size(sizeof(u8)) + /* ILA_ATTR_CSUM_MODE */ nla_total_size(sizeof(u8)) + /* ILA_ATTR_IDENT_TYPE */ nla_total_size(sizeof(u8)) + /* ILA_ATTR_HOOK_TYPE */ + nla_total_size(0) + /* ILA_ATTR_NOTIFY_DST */ + nla_total_size(0) + /* ILA_ATTR_NOTIFY_SRC */ 0; }