Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  spectrum_port_range.c

  Sprache: C
 

// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */

#include <linux/bits.h>
#include <linux/netlink.h>
#include <linux/refcount.h>
#include <linux/xarray.h>
#include <net/devlink.h>

#include "spectrum.h"

struct mlxsw_sp_port_range_reg {
 struct mlxsw_sp_port_range range;
 refcount_t refcount;
 u32 index;
};

struct mlxsw_sp_port_range_core {
 struct xarray prr_xa;
 struct xa_limit prr_ids;
 atomic_t prr_count;
};

static int
mlxsw_sp_port_range_reg_configure(struct mlxsw_sp *mlxsw_sp,
      const struct mlxsw_sp_port_range_reg *prr)
{
 char pprr_pl[MLXSW_REG_PPRR_LEN];

 /* We do not care if packet is IPv4/IPv6 and TCP/UDP, so set all four
 * fields.
 */

 mlxsw_reg_pprr_pack(pprr_pl, prr->index);
 mlxsw_reg_pprr_ipv4_set(pprr_pl, true);
 mlxsw_reg_pprr_ipv6_set(pprr_pl, true);
 mlxsw_reg_pprr_src_set(pprr_pl, prr->range.source);
 mlxsw_reg_pprr_dst_set(pprr_pl, !prr->range.source);
 mlxsw_reg_pprr_tcp_set(pprr_pl, true);
 mlxsw_reg_pprr_udp_set(pprr_pl, true);
 mlxsw_reg_pprr_port_range_min_set(pprr_pl, prr->range.min);
 mlxsw_reg_pprr_port_range_max_set(pprr_pl, prr->range.max);

 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pprr), pprr_pl);
}

static struct mlxsw_sp_port_range_reg *
mlxsw_sp_port_range_reg_create(struct mlxsw_sp *mlxsw_sp,
          const struct mlxsw_sp_port_range *range,
          struct netlink_ext_ack *extack)
{
 struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;
 struct mlxsw_sp_port_range_reg *prr;
 int err;

 prr = kzalloc(sizeof(*prr), GFP_KERNEL);
 if (!prr)
  return ERR_PTR(-ENOMEM);

 prr->range = *range;
 refcount_set(&prr->refcount, 1);

 err = xa_alloc(&pr_core->prr_xa, &prr->index, prr, pr_core->prr_ids,
         GFP_KERNEL);
 if (err) {
  if (err == -EBUSY)
   NL_SET_ERR_MSG_MOD(extack, "Exceeded number of port range registers");
  goto err_xa_alloc;
 }

 err = mlxsw_sp_port_range_reg_configure(mlxsw_sp, prr);
 if (err) {
  NL_SET_ERR_MSG_MOD(extack, "Failed to configure port range register");
  goto err_reg_configure;
 }

 atomic_inc(&pr_core->prr_count);

 return prr;

err_reg_configure:
 xa_erase(&pr_core->prr_xa, prr->index);
err_xa_alloc:
 kfree(prr);
 return ERR_PTR(err);
}

static void mlxsw_sp_port_range_reg_destroy(struct mlxsw_sp *mlxsw_sp,
         struct mlxsw_sp_port_range_reg *prr)
{
 struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;

 atomic_dec(&pr_core->prr_count);
 xa_erase(&pr_core->prr_xa, prr->index);
 kfree(prr);
}

static struct mlxsw_sp_port_range_reg *
mlxsw_sp_port_range_reg_find(struct mlxsw_sp *mlxsw_sp,
        const struct mlxsw_sp_port_range *range)
{
 struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;
 struct mlxsw_sp_port_range_reg *prr;
 unsigned long index;

 xa_for_each(&pr_core->prr_xa, index, prr) {
  if (prr->range.min == range->min &&
      prr->range.max == range->max &&
      prr->range.source == range->source)
   return prr;
 }

 return NULL;
}

int mlxsw_sp_port_range_reg_get(struct mlxsw_sp *mlxsw_sp,
    const struct mlxsw_sp_port_range *range,
    struct netlink_ext_ack *extack,
    u8 *p_prr_index)
{
 struct mlxsw_sp_port_range_reg *prr;

 prr = mlxsw_sp_port_range_reg_find(mlxsw_sp, range);
 if (prr) {
  refcount_inc(&prr->refcount);
  *p_prr_index = prr->index;
  return 0;
 }

 prr = mlxsw_sp_port_range_reg_create(mlxsw_sp, range, extack);
 if (IS_ERR(prr))
  return PTR_ERR(prr);

 *p_prr_index = prr->index;

 return 0;
}

void mlxsw_sp_port_range_reg_put(struct mlxsw_sp *mlxsw_sp, u8 prr_index)
{
 struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;
 struct mlxsw_sp_port_range_reg *prr;

 prr = xa_load(&pr_core->prr_xa, prr_index);
 if (WARN_ON(!prr))
  return;

 if (!refcount_dec_and_test(&prr->refcount))
  return;

 mlxsw_sp_port_range_reg_destroy(mlxsw_sp, prr);
}

static u64 mlxsw_sp_port_range_reg_occ_get(void *priv)
{
 struct mlxsw_sp_port_range_core *pr_core = priv;

 return atomic_read(&pr_core->prr_count);
}

int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp)
{
 struct mlxsw_sp_port_range_core *pr_core;
 struct mlxsw_core *core = mlxsw_sp->core;
 u64 max;

 if (!MLXSW_CORE_RES_VALID(core, ACL_MAX_L4_PORT_RANGE))
  return -EIO;
 max = MLXSW_CORE_RES_GET(core, ACL_MAX_L4_PORT_RANGE);

 /* Each port range register is represented using a single bit in the
 * two bytes "l4_port_range" ACL key element.
 */

 WARN_ON(max > BITS_PER_BYTE * sizeof(u16));

 pr_core = kzalloc(sizeof(*mlxsw_sp->pr_core), GFP_KERNEL);
 if (!pr_core)
  return -ENOMEM;
 mlxsw_sp->pr_core = pr_core;

 pr_core->prr_ids.max = max - 1;
 xa_init_flags(&pr_core->prr_xa, XA_FLAGS_ALLOC);

 devl_resource_occ_get_register(priv_to_devlink(core),
           MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
           mlxsw_sp_port_range_reg_occ_get,
           pr_core);

 return 0;
}

void mlxsw_sp_port_range_fini(struct mlxsw_sp *mlxsw_sp)
{
 struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;

 devl_resource_occ_get_unregister(priv_to_devlink(mlxsw_sp->core),
      MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS);
 WARN_ON(!xa_empty(&pr_core->prr_xa));
 xa_destroy(&pr_core->prr_xa);
 kfree(pr_core);
}

Messung V0.5 in Prozent
C=96 H=92 G=93

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-06-07) ¤

*© Formatika GbR, Deutschland






Entwurf

Ziele

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Ergonomie der
Schnittstellen

Diese beiden folgenden Angebotsgruppen bietet das Unternehmen

Angebot

Hier finden Sie eine Liste der Produkte des Unternehmens






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=434850
#Domains=655579