Skip to content

Commit 37b498f

Browse files
hadarhenzionSaeed Mahameed
authored andcommitted
net/mlx5e: Add neighbour hash table to the representors
Add hash table to the representors which is to be used by the next patch to save neighbours information in the driver. In order to offload IP tunnel encapsulation rules, the driver must find the tunnel dst neighbour according to the output device and the destination address given by the user. The next patch will cache the neighbors information in the driver to allow support in neigh update flow for tunnel encap rules. The neighbour entries are also saved in a list so we easily iterate over them when querying statistics in order to provide 'used' feedback to the kernel neighbour NUD core. Signed-off-by: Hadar Hen Zion <[email protected]> Reviewed-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 033354d commit 37b498f

File tree

2 files changed

+129
-8
lines changed

2 files changed

+129
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

Lines changed: 99 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,68 @@ void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
224224
mlx5_eswitch_sqs2vport_stop(esw, rep);
225225
}
226226

227+
static const struct rhashtable_params mlx5e_neigh_ht_params = {
228+
.head_offset = offsetof(struct mlx5e_neigh_hash_entry, rhash_node),
229+
.key_offset = offsetof(struct mlx5e_neigh_hash_entry, m_neigh),
230+
.key_len = sizeof(struct mlx5e_neigh),
231+
.automatic_shrinking = true,
232+
};
233+
234+
static int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
235+
{
236+
struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
237+
238+
INIT_LIST_HEAD(&neigh_update->neigh_list);
239+
return rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params);
240+
}
241+
242+
static void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv)
243+
{
244+
struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
245+
246+
rhashtable_destroy(&neigh_update->neigh_ht);
247+
}
248+
249+
static int mlx5e_rep_neigh_entry_insert(struct mlx5e_priv *priv,
250+
struct mlx5e_neigh_hash_entry *nhe)
251+
{
252+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
253+
int err;
254+
255+
err = rhashtable_insert_fast(&rpriv->neigh_update.neigh_ht,
256+
&nhe->rhash_node,
257+
mlx5e_neigh_ht_params);
258+
if (err)
259+
return err;
260+
261+
list_add(&nhe->neigh_list, &rpriv->neigh_update.neigh_list);
262+
263+
return err;
264+
}
265+
266+
static void mlx5e_rep_neigh_entry_remove(struct mlx5e_priv *priv,
267+
struct mlx5e_neigh_hash_entry *nhe)
268+
{
269+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
270+
271+
list_del(&nhe->neigh_list);
272+
273+
rhashtable_remove_fast(&rpriv->neigh_update.neigh_ht,
274+
&nhe->rhash_node,
275+
mlx5e_neigh_ht_params);
276+
}
277+
278+
static struct mlx5e_neigh_hash_entry *
279+
mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
280+
struct mlx5e_neigh *m_neigh)
281+
{
282+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
283+
struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
284+
285+
return rhashtable_lookup_fast(&neigh_update->neigh_ht, m_neigh,
286+
mlx5e_neigh_ht_params);
287+
}
288+
227289
static int mlx5e_rep_open(struct net_device *dev)
228290
{
229291
struct mlx5e_priv *priv = netdev_priv(dev);
@@ -540,26 +602,42 @@ static struct mlx5e_profile mlx5e_rep_profile = {
540602
static int
541603
mlx5e_nic_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
542604
{
543-
struct net_device *netdev = rep->netdev;
544-
struct mlx5e_priv *priv = netdev_priv(netdev);
605+
struct mlx5e_priv *priv = netdev_priv(rep->netdev);
606+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
607+
608+
int err;
609+
610+
if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
611+
err = mlx5e_add_sqs_fwd_rules(priv);
612+
if (err)
613+
return err;
614+
}
615+
616+
err = mlx5e_rep_neigh_init(rpriv);
617+
if (err)
618+
goto err_remove_sqs;
545619

546-
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
547-
return mlx5e_add_sqs_fwd_rules(priv);
548620
return 0;
621+
622+
err_remove_sqs:
623+
mlx5e_remove_sqs_fwd_rules(priv);
624+
return err;
549625
}
550626

551627
static void
552628
mlx5e_nic_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
553629
{
554-
struct net_device *netdev = rep->netdev;
555-
struct mlx5e_priv *priv = netdev_priv(netdev);
630+
struct mlx5e_priv *priv = netdev_priv(rep->netdev);
631+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
556632

557633
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
558634
mlx5e_remove_sqs_fwd_rules(priv);
559635

560636
/* clean (and re-init) existing uplink offloaded TC rules */
561637
mlx5e_tc_cleanup(priv);
562638
mlx5e_tc_init(priv);
639+
640+
mlx5e_rep_neigh_cleanup(rpriv);
563641
}
564642

565643
static int
@@ -591,15 +669,25 @@ mlx5e_vport_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
591669
goto err_destroy_netdev;
592670
}
593671

672+
err = mlx5e_rep_neigh_init(rpriv);
673+
if (err) {
674+
pr_warn("Failed to initialized neighbours handling for vport %d\n",
675+
rep->vport);
676+
goto err_detach_netdev;
677+
}
678+
594679
err = register_netdev(netdev);
595680
if (err) {
596681
pr_warn("Failed to register representor netdev for vport %d\n",
597682
rep->vport);
598-
goto err_detach_netdev;
683+
goto err_neigh_cleanup;
599684
}
600685

601686
return 0;
602687

688+
err_neigh_cleanup:
689+
mlx5e_rep_neigh_cleanup(rpriv);
690+
603691
err_detach_netdev:
604692
mlx5e_detach_netdev(netdev_priv(netdev));
605693

@@ -615,9 +703,12 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
615703
{
616704
struct net_device *netdev = rep->netdev;
617705
struct mlx5e_priv *priv = netdev_priv(netdev);
706+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
618707
void *ppriv = priv->ppriv;
619708

620-
unregister_netdev(netdev);
709+
unregister_netdev(rep->netdev);
710+
711+
mlx5e_rep_neigh_cleanup(rpriv);
621712
mlx5e_detach_netdev(priv);
622713
mlx5e_destroy_netdev(priv);
623714
kfree(ppriv); /* mlx5e_rep_priv */

drivers/net/ethernet/mellanox/mlx5/core/en_rep.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,41 @@
3434
#define __MLX5E_REP_H__
3535

3636
#include <net/ip_tunnels.h>
37+
#include <linux/rhashtable.h>
3738
#include "eswitch.h"
3839
#include "en.h"
3940

41+
struct mlx5e_neigh_update_table {
42+
struct rhashtable neigh_ht;
43+
/* Save the neigh hash entries in a list in addition to the hash table
44+
* (neigh_ht). In order to iterate easily over the neigh entries.
45+
* Used for stats query.
46+
*/
47+
struct list_head neigh_list;
48+
};
49+
4050
struct mlx5e_rep_priv {
4151
struct mlx5_eswitch_rep *rep;
52+
struct mlx5e_neigh_update_table neigh_update;
53+
};
54+
55+
struct mlx5e_neigh {
56+
struct net_device *dev;
57+
union {
58+
__be32 v4;
59+
struct in6_addr v6;
60+
} dst_ip;
61+
};
62+
63+
struct mlx5e_neigh_hash_entry {
64+
struct rhash_head rhash_node;
65+
struct mlx5e_neigh m_neigh;
66+
67+
/* Save the neigh hash entry in a list on the representor in
68+
* addition to the hash table. In order to iterate easily over the
69+
* neighbour entries. Used for stats query.
70+
*/
71+
struct list_head neigh_list;
4272
};
4373

4474
struct mlx5e_encap_entry {

0 commit comments

Comments
 (0)