aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <konstantinb@nvidia.com>2021-04-14 07:09:36 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-07-12 09:34:39 +0000
commit0e4cb0d5a487339cc7f5e151c466e20aeac1e4d9 (patch)
tree809fdc5b6a66df83d3e62df0e98b808741cfa625
parent559eaa44d91ad74973612843835a8248b3df7341 (diff)
downloadsrc-0e4cb0d5a487339cc7f5e151c466e20aeac1e4d9.tar.gz
src-0e4cb0d5a487339cc7f5e151c466e20aeac1e4d9.zip
mlx5en: remove all dynamic vxlan steering rules on close and reinstall on open
Reviewed by: hselasky Sponsored by: Mellanox Technologies/NVidia Networking MFC after: 1 week
-rw-r--r--sys/dev/mlx5/mlx5_en/en.h4
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c36
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c10
3 files changed, 49 insertions, 1 deletions
diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
index ab30c7e2ca90..e4b66bea8f60 100644
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -948,6 +948,7 @@ struct mlx5e_vxlan_db_el {
u_int refcount;
u_int proto;
u_int port;
+ bool installed;
struct mlx5_flow_rule *vxlan_ft_rule;
TAILQ_ENTRY(mlx5e_vxlan_db_el) link;
};
@@ -1149,6 +1150,9 @@ void mlx5e_vxlan_start(void *arg, struct ifnet *ifp, sa_family_t family,
void mlx5e_vxlan_stop(void *arg, struct ifnet *ifp, sa_family_t family,
u_int port);
+int mlx5e_add_all_vxlan_rules(struct mlx5e_priv *priv);
+void mlx5e_del_all_vxlan_rules(struct mlx5e_priv *priv);
+
static inline void
mlx5e_tx_notify_hw(struct mlx5e_sq *sq, u32 *wqe)
{
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c b/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c
index 648dc199157c..a493e530a4c8 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c
@@ -1840,13 +1840,15 @@ mlx5e_add_vxlan_rule(struct mlx5e_priv *priv, sa_family_t family, u_int port)
el = mlx5e_vxlan_find_db_el(priv, proto, port);
if (el != NULL) {
el->refcount++;
- return (0);
+ if (el->installed)
+ return (0);
}
el = mlx5e_vxlan_alloc_db_el(priv, proto, port);
err = mlx5e_add_vxlan_rule_from_db(priv, el);
if (err == 0) {
TAILQ_INSERT_TAIL(&priv->vxlan.head, el, link);
+ el->installed = true;
} else {
kvfree(el);
}
@@ -1905,6 +1907,25 @@ add_vxlan_rule_out:
return (err);
}
+int
+mlx5e_add_all_vxlan_rules(struct mlx5e_priv *priv)
+{
+ struct mlx5e_vxlan_db_el *el;
+ int err;
+
+ err = 0;
+ TAILQ_FOREACH(el, &priv->vxlan.head, link) {
+ if (el->installed)
+ continue;
+ err = mlx5e_add_vxlan_rule_from_db(priv, el);
+ if (err != 0)
+ break;
+ el->installed = false;
+ }
+
+ return (err);
+}
+
static int
mlx5e_del_vxlan_rule(struct mlx5e_priv *priv, sa_family_t family, u_int port)
{
@@ -1930,6 +1951,19 @@ mlx5e_del_vxlan_rule(struct mlx5e_priv *priv, sa_family_t family, u_int port)
return (0);
}
+void
+mlx5e_del_all_vxlan_rules(struct mlx5e_priv *priv)
+{
+ struct mlx5e_vxlan_db_el *el;
+
+ TAILQ_FOREACH(el, &priv->vxlan.head, link) {
+ if (!el->installed)
+ continue;
+ mlx5_del_flow_rule(el->vxlan_ft_rule);
+ el->installed = false;
+ }
+}
+
static void
mlx5e_del_vxlan_catchall_rule(struct mlx5e_priv *priv)
{
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index 26bd5e00d22d..9a01940ca90c 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -3144,6 +3144,12 @@ mlx5e_open_locked(struct ifnet *ifp)
"mlx5e_add_all_vlan_rules failed, %d\n", err);
goto err_close_flow_table;
}
+ err = mlx5e_add_all_vxlan_rules(priv);
+ if (err) {
+ mlx5_en_err(ifp,
+ "mlx5e_add_all_vxlan_rules failed, %d\n", err);
+ goto err_del_vlan_rules;
+ }
set_bit(MLX5E_STATE_OPENED, &priv->state);
mlx5e_update_carrier(priv);
@@ -3151,6 +3157,9 @@ mlx5e_open_locked(struct ifnet *ifp)
return (0);
+err_del_vlan_rules:
+ mlx5e_del_all_vlan_rules(priv);
+
err_close_flow_table:
mlx5e_close_flow_table(priv);
@@ -3204,6 +3213,7 @@ mlx5e_close_locked(struct ifnet *ifp)
mlx5e_set_rx_mode_core(priv);
mlx5e_del_all_vlan_rules(priv);
+ mlx5e_del_all_vxlan_rules(priv);
if_link_state_change(priv->ifp, LINK_STATE_DOWN);
mlx5e_close_flow_table(priv);
mlx5e_close_tirs(priv, true);