mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Paolo Abeni <pabeni@redhat.com>
To: Yevhen Orlov <yevhen.orlov@plvision.eu>, netdev@vger.kernel.org
Cc: Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>,
	Taras Chornyi <taras.chornyi@plvision.eu>,
	Mickey Rachamim <mickeyr@marvell.com>,
	Serhiy Pshyk <serhiy.pshyk@plvision.eu>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
	Stephen Hemminger <stephen@networkplumber.org>,
	linux-kernel@vger.kernel.org,
	Taras Chornyi <tchornyi@marvell.com>,
	Oleksandr Mazur <oleksandr.mazur@plvision.eu>
Subject: Re: [PATCH net-next v6 8/9] net: marvell: prestera: Add neighbour cache accounting
Date: Thu, 22 Sep 2022 12:16:52 +0200	[thread overview]
Message-ID: <dbd40afb1f5d9e8c3866f7a3dd98d970f3c76f9a.camel@redhat.com> (raw)
In-Reply-To: <20220918194700.19905-9-yevhen.orlov@plvision.eu>

On Sun, 2022-09-18 at 22:46 +0300, Yevhen Orlov wrote:
> Move forward and use new PRESTERA_FIB_TYPE_UC_NH to provide basic
> nexthop routes support.
> Provide deinitialization sequence for all created router objects.
> 
> Limitations:
> - Only "local" and "main" tables supported
> - Only generic interfaces supported for router (no bridges or vlans)
> 
> Co-developed-by: Taras Chornyi <tchornyi@marvell.com>
> Signed-off-by: Taras Chornyi <tchornyi@marvell.com>
> Co-developed-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
> Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
> Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
> ---
>  .../net/ethernet/marvell/prestera/prestera.h  |   1 +
>  .../marvell/prestera/prestera_router.c        | 815 +++++++++++++++++-
>  2 files changed, 813 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera.h b/drivers/net/ethernet/marvell/prestera/prestera.h
> index 2f2f80e7e358..540a36069b79 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera.h
> +++ b/drivers/net/ethernet/marvell/prestera/prestera.h
> @@ -316,6 +316,7 @@ struct prestera_router {
>  	struct rhashtable nh_neigh_ht;
>  	struct rhashtable nexthop_group_ht;
>  	struct rhashtable fib_ht;
> +	struct rhashtable kern_neigh_cache_ht;
>  	struct rhashtable kern_fib_cache_ht;
>  	struct notifier_block inetaddr_nb;
>  	struct notifier_block inetaddr_valid_nb;
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> index a6af3b53838e..771d123345ac 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_router.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> @@ -8,11 +8,30 @@
>  #include <net/switchdev.h>
>  #include <linux/rhashtable.h>
>  #include <net/nexthop.h>
> +#include <net/arp.h>
> +#include <linux/if_vlan.h>
> +#include <linux/if_macvlan.h>
>  #include <net/netevent.h>
>  
>  #include "prestera.h"
>  #include "prestera_router_hw.h"
>  
> +struct prestera_kern_neigh_cache_key {
> +	struct prestera_ip_addr addr;
> +	struct net_device *dev;
> +};
> +
> +struct prestera_kern_neigh_cache {
> +	struct prestera_kern_neigh_cache_key key;
> +	struct rhash_head ht_node;
> +	struct list_head kern_fib_cache_list;
> +	/* Hold prepared nh_neigh info if is in_kernel */
> +	struct prestera_neigh_info nh_neigh_info;
> +	/* Indicate if neighbour is reachable by direct route */
> +	bool reachable;
> +	/* Lock cache if neigh is present in kernel */
> +	bool in_kernel;
> +};
>  struct prestera_kern_fib_cache_key {
>  	struct prestera_ip_addr addr;
>  	u32 prefix_len;
> @@ -25,9 +44,15 @@ struct prestera_kern_fib_cache {
>  	struct {
>  		struct prestera_fib_key fib_key;
>  		enum prestera_fib_type fib_type;
> +		struct prestera_nexthop_group_key nh_grp_key;
>  	} lpm_info; /* hold prepared lpm info */
>  	/* Indicate if route is not overlapped by another table */
>  	struct rhash_head ht_node; /* node of prestera_router */
> +	struct prestera_kern_neigh_cache_head {
> +		struct prestera_kern_fib_cache *this;
> +		struct list_head head;
> +		struct prestera_kern_neigh_cache *n_cache;
> +	} kern_neigh_cache_head[PRESTERA_NHGR_SIZE_MAX];
>  	union {
>  		struct fib_notifier_info info; /* point to any of 4/6 */
>  		struct fib_entry_notifier_info fen4_info;
> @@ -35,6 +60,13 @@ struct prestera_kern_fib_cache {
>  	bool reachable;
>  };
>  
> +static const struct rhashtable_params __prestera_kern_neigh_cache_ht_params = {
> +	.key_offset  = offsetof(struct prestera_kern_neigh_cache, key),
> +	.head_offset = offsetof(struct prestera_kern_neigh_cache, ht_node),
> +	.key_len     = sizeof(struct prestera_kern_neigh_cache_key),
> +	.automatic_shrinking = true,
> +};
> +
>  static const struct rhashtable_params __prestera_kern_fib_cache_ht_params = {
>  	.key_offset  = offsetof(struct prestera_kern_fib_cache, key),
>  	.head_offset = offsetof(struct prestera_kern_fib_cache, ht_node),
> @@ -67,6 +99,278 @@ prestera_util_fen_info2fib_cache_key(struct fib_notifier_info *info,
>  	key->kern_tb_id = fen_info->tb_id;
>  }
>  
> +static int prestera_util_nhc2nc_key(struct prestera_switch *sw,
> +				    struct fib_nh_common *nhc,
> +				    struct prestera_kern_neigh_cache_key *nk)
> +{
> +	memset(nk, 0, sizeof(*nk));
> +	if (nhc->nhc_gw_family == AF_INET) {
> +		nk->addr.v = PRESTERA_IPV4;
> +		nk->addr.u.ipv4 = nhc->nhc_gw.ipv4;
> +	} else {
> +		nk->addr.v = PRESTERA_IPV6;
> +		nk->addr.u.ipv6 = nhc->nhc_gw.ipv6;
> +	}
> +
> +	nk->dev = nhc->nhc_dev;
> +	return 0;
> +}
> +
> +static void
> +prestera_util_nc_key2nh_key(struct prestera_kern_neigh_cache_key *ck,
> +			    struct prestera_nh_neigh_key *nk)
> +{
> +	memset(nk, 0, sizeof(*nk));
> +	nk->addr = ck->addr;
> +	nk->rif = (void *)ck->dev;
> +}
> +
> +static bool
> +prestera_util_nhc_eq_n_cache_key(struct prestera_switch *sw,
> +				 struct fib_nh_common *nhc,
> +				 struct prestera_kern_neigh_cache_key *nk)
> +{
> +	struct prestera_kern_neigh_cache_key tk;
> +	int err;
> +
> +	err = prestera_util_nhc2nc_key(sw, nhc, &tk);
> +	if (err)
> +		return false;
> +
> +	if (memcmp(&tk, nk, sizeof(tk)))
> +		return false;
> +
> +	return true;
> +}
> +
> +static int
> +prestera_util_neigh2nc_key(struct prestera_switch *sw, struct neighbour *n,
> +			   struct prestera_kern_neigh_cache_key *key)
> +{
> +	memset(key, 0, sizeof(*key));
> +	if (n->tbl->family == AF_INET) {
> +		key->addr.v = PRESTERA_IPV4;
> +		key->addr.u.ipv4 = *(__be32 *)n->primary_key;
> +	} else {
> +		return -ENOENT;
> +	}
> +
> +	key->dev = n->dev;
> +
> +	return 0;
> +}
> +
> +static bool __prestera_fi_is_direct(struct fib_info *fi)
> +{
> +	struct fib_nh *fib_nh;
> +
> +	if (fib_info_num_path(fi) == 1) {
> +		fib_nh = fib_info_nh(fi, 0);
> +		if (fib_nh->fib_nh_gw_family == AF_UNSPEC)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +static bool prestera_fi_is_direct(struct fib_info *fi)
> +{
> +	if (fi->fib_type != RTN_UNICAST)
> +		return false;
> +
> +	return __prestera_fi_is_direct(fi);
> +}
> +
> +static bool prestera_fi_is_nh(struct fib_info *fi)
> +{
> +	if (fi->fib_type != RTN_UNICAST)
> +		return false;
> +
> +	return !__prestera_fi_is_direct(fi);
> +}
> +
> +static bool __prestera_fi6_is_direct(struct fib6_info *fi)
> +{
> +	if (!fi->fib6_nh->nh_common.nhc_gw_family)
> +		return true;
> +
> +	return false;
> +}
> +
> +static bool prestera_fi6_is_direct(struct fib6_info *fi)
> +{
> +	if (fi->fib6_type != RTN_UNICAST)
> +		return false;
> +
> +	return __prestera_fi6_is_direct(fi);
> +}
> +
> +static bool prestera_fi6_is_nh(struct fib6_info *fi)
> +{
> +	if (fi->fib6_type != RTN_UNICAST)
> +		return false;
> +
> +	return !__prestera_fi6_is_direct(fi);
> +}
> +
> +static bool prestera_fib_info_is_direct(struct fib_notifier_info *info)
> +{
> +	struct fib6_entry_notifier_info *fen6_info =
> +		container_of(info, struct fib6_entry_notifier_info, info);
> +	struct fib_entry_notifier_info *fen_info =
> +		container_of(info, struct fib_entry_notifier_info, info);
> +
> +	if (info->family == AF_INET)
> +		return prestera_fi_is_direct(fen_info->fi);
> +	else
> +		return prestera_fi6_is_direct(fen6_info->rt);
> +}
> +
> +static bool prestera_fib_info_is_nh(struct fib_notifier_info *info)
> +{
> +	struct fib6_entry_notifier_info *fen6_info =
> +		container_of(info, struct fib6_entry_notifier_info, info);
> +	struct fib_entry_notifier_info *fen_info =
> +		container_of(info, struct fib_entry_notifier_info, info);
> +
> +	if (info->family == AF_INET)
> +		return prestera_fi_is_nh(fen_info->fi);
> +	else
> +		return prestera_fi6_is_nh(fen6_info->rt);
> +}
> +
> +/* must be called with rcu_read_lock() */
> +static int prestera_util_kern_get_route(struct fib_result *res, u32 tb_id,
> +					__be32 *addr)
> +{
> +	struct fib_table *tb;
> +	struct flowi4 fl4;
> +	int ret;
> +
> +	/* TODO: walkthrough appropriate tables in kernel
> +	 * to know if the same prefix exists in several tables
> +	 */
> +	tb = fib_new_table(&init_net, tb_id);
> +	if (!tb)
> +		return -ENOENT;
> +
> +	memset(&fl4, 0, sizeof(fl4));
> +	fl4.daddr = *addr;
> +	ret = fib_table_lookup(tb, &fl4, res, FIB_LOOKUP_NOREF);
> +	if (ret)
> +		return ret;

Likely you can use fib_lookup() instead of all the above.

Thanks,

Paolo


  reply	other threads:[~2022-09-22 10:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-18 19:46 [PATCH net-next v6 0/9] net: marvell: prestera: add nexthop routes offloading Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 1/9] net: marvell: prestera: Add router nexthops ABI Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 2/9] net: marvell: prestera: Add cleanup of allocated fib_nodes Yevhen Orlov
2022-09-22 10:15   ` Paolo Abeni
2022-09-18 19:46 ` [PATCH net-next v6 3/9] net: marvell: prestera: Add strict cleanup of fib arbiter Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 4/9] net: marvell: prestera: add delayed wq and flush wq on deinit Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 5/9] net: marvell: prestera: Add length macros for prestera_ip_addr Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 6/9] net: marvell: prestera: Add heplers to interact with fib_notifier_info Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 7/9] net: marvell: prestera: add stub handler neighbour events Yevhen Orlov
2022-09-18 19:46 ` [PATCH net-next v6 8/9] net: marvell: prestera: Add neighbour cache accounting Yevhen Orlov
2022-09-22 10:16   ` Paolo Abeni [this message]
2022-09-18 19:47 ` [PATCH net-next v6 9/9] net: marvell: prestera: Propagate nh state from hw to kernel Yevhen Orlov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dbd40afb1f5d9e8c3866f7a3dd98d970f3c76f9a.camel@redhat.com \
    --to=pabeni@redhat.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mickeyr@marvell.com \
    --cc=netdev@vger.kernel.org \
    --cc=oleksandr.mazur@plvision.eu \
    --cc=serhiy.pshyk@plvision.eu \
    --cc=stephen@networkplumber.org \
    --cc=taras.chornyi@plvision.eu \
    --cc=tchornyi@marvell.com \
    --cc=volodymyr.mytnyk@plvision.eu \
    --cc=yevhen.orlov@plvision.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®