Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  port_tun.c   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2019 Mellanox Technologies. */

#include <linux/mlx5/driver.h>
#include <linux/mlx5/port.h>
#include "mlx5_core.h"
#include "lib/port_tun.h"

struct mlx5_port_tun_entropy_flags {
 bool force_supported, force_enabled;
 bool calc_supported, calc_enabled;
 bool gre_calc_supported, gre_calc_enabled;
};

static void mlx5_query_port_tun_entropy(struct mlx5_core_dev *mdev,
     struct mlx5_port_tun_entropy_flags *entropy_flags)
{
 u32 out[MLX5_ST_SZ_DW(pcmr_reg)];
 /* Default values for FW which do not support MLX5_REG_PCMR */
 entropy_flags->force_supported = false;
 entropy_flags->calc_supported = false;
 entropy_flags->gre_calc_supported = false;
 entropy_flags->force_enabled = false;
 entropy_flags->calc_enabled = true;
 entropy_flags->gre_calc_enabled = true;

 if (!MLX5_CAP_GEN(mdev, ports_check))
  return;

 if (mlx5_query_ports_check(mdev, out, sizeof(out)))
  return;

 entropy_flags->force_supported = !!(MLX5_GET(pcmr_reg, out, entropy_force_cap));
 entropy_flags->calc_supported = !!(MLX5_GET(pcmr_reg, out, entropy_calc_cap));
 entropy_flags->gre_calc_supported = !!(MLX5_GET(pcmr_reg, out, entropy_gre_calc_cap));
 entropy_flags->force_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_force));
 entropy_flags->calc_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_calc));
 entropy_flags->gre_calc_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_gre_calc));
}

static int mlx5_set_port_tun_entropy_calc(struct mlx5_core_dev *mdev, u8 enable,
       u8 force)
{
 u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {0};
 int err;

 err = mlx5_query_ports_check(mdev, in, sizeof(in));
 if (err)
  return err;
 MLX5_SET(pcmr_reg, in, local_port, 1);
 MLX5_SET(pcmr_reg, in, entropy_force, force);
 MLX5_SET(pcmr_reg, in, entropy_calc, enable);
 return mlx5_set_ports_check(mdev, in, sizeof(in));
}

static int mlx5_set_port_gre_tun_entropy_calc(struct mlx5_core_dev *mdev,
           u8 enable, u8 force)
{
 u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {0};
 int err;

 err = mlx5_query_ports_check(mdev, in, sizeof(in));
 if (err)
  return err;
 MLX5_SET(pcmr_reg, in, local_port, 1);
 MLX5_SET(pcmr_reg, in, entropy_force, force);
 MLX5_SET(pcmr_reg, in, entropy_gre_calc, enable);
 return mlx5_set_ports_check(mdev, in, sizeof(in));
}

void mlx5_init_port_tun_entropy(struct mlx5_tun_entropy *tun_entropy,
    struct mlx5_core_dev *mdev)
{
 struct mlx5_port_tun_entropy_flags entropy_flags;

 tun_entropy->mdev = mdev;
 mutex_init(&tun_entropy->lock);
 mlx5_query_port_tun_entropy(mdev, &entropy_flags);
 tun_entropy->num_enabling_entries = 0;
 tun_entropy->num_disabling_entries = 0;
 tun_entropy->enabled = entropy_flags.calc_supported ?
          entropy_flags.calc_enabled : true;
}

static int mlx5_set_entropy(struct mlx5_tun_entropy *tun_entropy,
       int reformat_type, bool enable)
{
 struct mlx5_port_tun_entropy_flags entropy_flags;
 int err;

 mlx5_query_port_tun_entropy(tun_entropy->mdev, &entropy_flags);
 /* Tunnel entropy calculation may be controlled either on port basis
 * for all tunneling protocols or specifically for GRE protocol.
 * Prioritize GRE protocol control (if capable) over global port
 * configuration.
 */

 if (entropy_flags.gre_calc_supported &&
     reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE) {
  if (!entropy_flags.force_supported)
   return 0;
  err = mlx5_set_port_gre_tun_entropy_calc(tun_entropy->mdev,
        enable, !enable);
  if (err)
   return err;
 } else if (entropy_flags.calc_supported) {
  /* Other applications may change the global FW entropy
 * calculations settings. Check that the current entropy value
 * is the negative of the updated value.
 */

  if (entropy_flags.force_enabled &&
      enable == entropy_flags.calc_enabled) {
   mlx5_core_warn(tun_entropy->mdev,
           "Unexpected entropy calc setting - expected %d",
           !entropy_flags.calc_enabled);
   return -EOPNOTSUPP;
  }
  /* GRE requires disabling entropy calculation. if there are
 * enabling entries (i.e VXLAN) we cannot turn it off for them,
 * thus fail.
 */

  if (tun_entropy->num_enabling_entries)
   return -EOPNOTSUPP;
  err = mlx5_set_port_tun_entropy_calc(tun_entropy->mdev, enable,
           entropy_flags.force_supported);
  if (err)
   return err;
  tun_entropy->enabled = enable;
  /* if we turn on the entropy we don't need to force it anymore */
  if (entropy_flags.force_supported && enable) {
   err = mlx5_set_port_tun_entropy_calc(tun_entropy->mdev, 1, 0);
   if (err)
    return err;
  }
 }

 return 0;
}

/* the function manages the refcount for enabling/disabling tunnel types.
 * the return value indicates if the inc is successful or not, depending on
 * entropy capabilities and configuration.
 */

int mlx5_tun_entropy_refcount_inc(struct mlx5_tun_entropy *tun_entropy,
      int reformat_type)
{
 int err = -EOPNOTSUPP;

 mutex_lock(&tun_entropy->lock);
 if ((reformat_type == MLX5_REFORMAT_TYPE_L2_TO_VXLAN ||
      reformat_type == MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL) &&
     tun_entropy->enabled) {
  /* in case entropy calculation is enabled for all tunneling
 * types, it is ok for VXLAN, so approve.
 * otherwise keep the error default.
 */

  tun_entropy->num_enabling_entries++;
  err = 0;
 } else if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE) {
  /* turn off the entropy only for the first GRE rule.
 * for the next rules the entropy was already disabled
 * successfully.
 */

  if (tun_entropy->num_disabling_entries == 0)
   err = mlx5_set_entropy(tun_entropy, reformat_type, 0);
  else
   err = 0;
  if (!err)
   tun_entropy->num_disabling_entries++;
 }
 mutex_unlock(&tun_entropy->lock);

 return err;
}

void mlx5_tun_entropy_refcount_dec(struct mlx5_tun_entropy *tun_entropy,
       int reformat_type)
{
 mutex_lock(&tun_entropy->lock);
 if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_VXLAN)
  tun_entropy->num_enabling_entries--;
 else if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE &&
   --tun_entropy->num_disabling_entries == 0)
  mlx5_set_entropy(tun_entropy, reformat_type, 1);
 mutex_unlock(&tun_entropy->lock);
}


Messung V0.5
C=98 H=90 G=94

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge