All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.