#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/rhashtable.h>
#include <linux/bitops.h>
#include <linux/in6.h>
#include <linux/notifier.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/if_bridge.h>
#include <linux/socket.h>
#include <linux/route.h>
#include <linux/gcd.h>
#include <linux/if_macvlan.h>
#include <linux/refcount.h>
#include <linux/jhash.h>
#include <linux/net_namespace.h>
#include <linux/mutex.h>
#include <linux/genalloc.h>
#include <linux/xarray.h>
#include <net/netevent.h>
#include <net/neighbour.h>
#include <net/arp.h>
#include <net/inet_dscp.h>
#include <net/ip_fib.h>
#include <net/ip6_fib.h>
#include <net/nexthop.h>
#include <net/fib_rules.h>
#include <net/ip_tunnels.h>
#include <net/l3mdev.h>
#include <net/addrconf.h>
#include <net/ndisc.h>
#include <net/ipv6.h>
#include <net/fib_notifier.h>
#include <net/switchdev.h>
#include "spectrum.h"
#include "core.h"
#include "reg.h"
#include "spectrum_cnt.h"
#include "spectrum_dpipe.h"
#include "spectrum_ipip.h"
#include "spectrum_mr.h"
#include "spectrum_mr_tcam.h"
#include "spectrum_router.h"
#include "spectrum_span.h"
struct mlxsw_sp_fib;
struct mlxsw_sp_vr;
struct mlxsw_sp_lpm_tree;
struct mlxsw_sp_rif_ops;
struct mlxsw_sp_crif_key { … };
struct mlxsw_sp_crif { … };
static const struct rhashtable_params mlxsw_sp_crif_ht_params = …;
struct mlxsw_sp_rif { … };
static struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
{ … }
struct mlxsw_sp_rif_params { … };
struct mlxsw_sp_rif_subport { … };
struct mlxsw_sp_rif_ipip_lb { … };
struct mlxsw_sp_rif_params_ipip_lb { … };
struct mlxsw_sp_rif_ops { … };
struct mlxsw_sp_rif_mac_profile { … };
struct mlxsw_sp_router_ops { … };
static struct mlxsw_sp_rif *
mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev);
static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree);
static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree);
static int mlxsw_sp_vr_lpm_tree_bind(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_fib *fib,
u8 tree_id);
static int mlxsw_sp_vr_lpm_tree_unbind(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_fib *fib);
static unsigned int *
mlxsw_sp_rif_p_counter_get(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir)
{ … }
static bool
mlxsw_sp_rif_counter_valid_get(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir)
{ … }
static void
mlxsw_sp_rif_counter_valid_set(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir,
bool valid)
{ … }
static int mlxsw_sp_rif_counter_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
unsigned int counter_index, bool enable,
enum mlxsw_sp_rif_counter_dir dir)
{ … }
int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir, u64 *cnt)
{ … }
struct mlxsw_sp_rif_counter_set_basic { … };
static int
mlxsw_sp_rif_counter_fetch_clear(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir,
struct mlxsw_sp_rif_counter_set_basic *set)
{ … }
static int mlxsw_sp_rif_counter_clear(struct mlxsw_sp *mlxsw_sp,
unsigned int counter_index)
{ … }
int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir)
{ … }
void mlxsw_sp_rif_counter_free(struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir)
{ … }
static void mlxsw_sp_rif_counters_alloc(struct mlxsw_sp_rif *rif)
{ … }
static void mlxsw_sp_rif_counters_free(struct mlxsw_sp_rif *rif)
{ … }
#define MLXSW_SP_PREFIX_COUNT …
struct mlxsw_sp_prefix_usage { … };
#define mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) …
static bool
mlxsw_sp_prefix_usage_eq(struct mlxsw_sp_prefix_usage *prefix_usage1,
struct mlxsw_sp_prefix_usage *prefix_usage2)
{ … }
static void
mlxsw_sp_prefix_usage_cpy(struct mlxsw_sp_prefix_usage *prefix_usage1,
struct mlxsw_sp_prefix_usage *prefix_usage2)
{ … }
static void
mlxsw_sp_prefix_usage_set(struct mlxsw_sp_prefix_usage *prefix_usage,
unsigned char prefix_len)
{ … }
static void
mlxsw_sp_prefix_usage_clear(struct mlxsw_sp_prefix_usage *prefix_usage,
unsigned char prefix_len)
{ … }
struct mlxsw_sp_fib_key { … };
enum mlxsw_sp_fib_entry_type { … };
struct mlxsw_sp_nexthop_group_info;
struct mlxsw_sp_nexthop_group;
struct mlxsw_sp_fib_entry;
struct mlxsw_sp_fib_node { … };
struct mlxsw_sp_fib_entry_decap { … };
struct mlxsw_sp_fib_entry { … };
struct mlxsw_sp_fib4_entry { … };
struct mlxsw_sp_fib6_entry { … };
struct mlxsw_sp_rt6 { … };
struct mlxsw_sp_lpm_tree { … };
struct mlxsw_sp_fib { … };
struct mlxsw_sp_vr { … };
static const struct rhashtable_params mlxsw_sp_fib_ht_params;
static struct mlxsw_sp_fib *mlxsw_sp_fib_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_vr *vr,
enum mlxsw_sp_l3proto proto)
{ … }
static void mlxsw_sp_fib_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib *fib)
{ … }
static struct mlxsw_sp_lpm_tree *
mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_lpm_tree_alloc(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
static void mlxsw_sp_lpm_tree_free(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
static int
mlxsw_sp_lpm_tree_left_struct_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_prefix_usage *prefix_usage,
struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
static struct mlxsw_sp_lpm_tree *
mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_prefix_usage *prefix_usage,
enum mlxsw_sp_l3proto proto)
{ … }
static void mlxsw_sp_lpm_tree_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
static struct mlxsw_sp_lpm_tree *
mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_prefix_usage *prefix_usage,
enum mlxsw_sp_l3proto proto)
{ … }
static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree)
{ … }
#define MLXSW_SP_LPM_TREE_MIN …
static int mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_lpm_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static bool mlxsw_sp_vr_is_used(const struct mlxsw_sp_vr *vr)
{ … }
static struct mlxsw_sp_vr *mlxsw_sp_vr_find_unused(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_vr_lpm_tree_bind(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_fib *fib, u8 tree_id)
{ … }
static int mlxsw_sp_vr_lpm_tree_unbind(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_fib *fib)
{ … }
static u32 mlxsw_sp_fix_tb_id(u32 tb_id)
{ … }
static struct mlxsw_sp_vr *mlxsw_sp_vr_find(struct mlxsw_sp *mlxsw_sp,
u32 tb_id)
{ … }
int mlxsw_sp_router_tb_id_vr_id(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
u16 *vr_id)
{ … }
static struct mlxsw_sp_fib *mlxsw_sp_vr_fib(const struct mlxsw_sp_vr *vr,
enum mlxsw_sp_l3proto proto)
{ … }
static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
u32 tb_id,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_vr_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_vr *vr)
{ … }
static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_vr_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr)
{ … }
static bool
mlxsw_sp_vr_lpm_tree_should_replace(struct mlxsw_sp_vr *vr,
enum mlxsw_sp_l3proto proto, u8 tree_id)
{ … }
static int mlxsw_sp_vr_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib *fib,
struct mlxsw_sp_lpm_tree *new_tree)
{ … }
static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib *fib,
struct mlxsw_sp_lpm_tree *new_tree)
{ … }
static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp);
static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)
{ … }
static void
mlxsw_sp_crif_init(struct mlxsw_sp_crif *crif, struct net_device *dev)
{ … }
static struct mlxsw_sp_crif *
mlxsw_sp_crif_alloc(struct net_device *dev)
{ … }
static void mlxsw_sp_crif_free(struct mlxsw_sp_crif *crif)
{ … }
static int mlxsw_sp_crif_insert(struct mlxsw_sp_router *router,
struct mlxsw_sp_crif *crif)
{ … }
static void mlxsw_sp_crif_remove(struct mlxsw_sp_router *router,
struct mlxsw_sp_crif *crif)
{ … }
static struct mlxsw_sp_crif *
mlxsw_sp_crif_lookup(struct mlxsw_sp_router *router,
const struct net_device *dev)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack);
static struct mlxsw_sp_rif_ipip_lb *
mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
struct net_device *ol_dev,
struct netlink_ext_ack *extack)
{ … }
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
struct net_device *ol_dev)
{ … }
static void mlxsw_sp_ipip_entry_dealloc(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static bool
mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,
const enum mlxsw_sp_l3proto ul_proto,
union mlxsw_sp_l3addr saddr,
u32 ul_tb_id,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static int mlxsw_sp_ipip_decap_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt)
{ … }
static void mlxsw_sp_ipip_decap_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt)
{ … }
static int
mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static struct mlxsw_sp_fib_node *
mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
size_t addr_len, unsigned char prefix_len);
static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry);
static void
mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static void
mlxsw_sp_ipip_entry_promote_decap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
struct mlxsw_sp_fib_entry *decap_fib_entry)
{ … }
static struct mlxsw_sp_fib_entry *
mlxsw_sp_router_ip2me_fib_entry_find(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
enum mlxsw_sp_l3proto proto,
const union mlxsw_sp_l3addr *addr,
enum mlxsw_sp_fib_entry_type type)
{ … }
static struct mlxsw_sp_fib_entry *
mlxsw_sp_ipip_entry_find_decap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_create(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
struct net_device *ol_dev)
{ … }
static void
mlxsw_sp_ipip_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static bool
mlxsw_sp_ipip_entry_matches_decap(struct mlxsw_sp *mlxsw_sp,
const struct net_device *ul_dev,
enum mlxsw_sp_l3proto ul_proto,
union mlxsw_sp_l3addr ul_dip,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp, int ul_dev_ifindex,
enum mlxsw_sp_l3proto ul_proto,
union mlxsw_sp_l3addr ul_dip)
{ … }
static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev,
enum mlxsw_sp_ipip_type *p_type)
{ … }
static bool mlxsw_sp_netdev_is_ipip_ol(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev)
{ … }
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_find_by_ol_dev(struct mlxsw_sp *mlxsw_sp,
const struct net_device *ol_dev)
{ … }
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_find_by_ul_dev(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *ul_dev,
struct mlxsw_sp_ipip_entry *start)
{ … }
static bool mlxsw_sp_netdev_is_ipip_ul(struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev)
{ … }
static bool mlxsw_sp_netdevice_ipip_can_offload(struct mlxsw_sp *mlxsw_sp,
const struct net_device *ol_dev,
enum mlxsw_sp_ipip_type ipipt)
{ … }
static int mlxsw_sp_netdevice_ipip_ol_reg_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev)
{ … }
static void mlxsw_sp_netdevice_ipip_ol_unreg_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev)
{ … }
static void
mlxsw_sp_ipip_entry_ol_up_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static int
mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif, u16 ul_vr_id,
u16 ul_rif_id, bool enable)
{ … }
static int mlxsw_sp_netdevice_ipip_ol_update_mtu(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev)
{ … }
static void mlxsw_sp_netdevice_ipip_ol_up_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev)
{ … }
static void
mlxsw_sp_ipip_entry_ol_down_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev)
{ … }
static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif);
static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *old_rif,
struct mlxsw_sp_rif *new_rif,
bool migrate_nhs)
{ … }
static int
mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
bool keep_encap,
struct netlink_ext_ack *extack)
{ … }
int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
bool recreate_loopback,
bool keep_encap,
bool update_nexthops,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_netdevice_ipip_ol_vrf_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_netdevice_ipip_ul_vrf_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
struct net_device *ul_dev,
bool *demote_this,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_netdevice_ipip_ul_up_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
struct net_device *ul_dev)
{ … }
static int
mlxsw_sp_netdevice_ipip_ul_down_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
struct net_device *ul_dev)
{ … }
static int
mlxsw_sp_netdevice_ipip_ol_change_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev,
struct netlink_ext_ack *extack)
{ … }
void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
bool
mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_l3proto ul_proto,
union mlxsw_sp_l3addr saddr,
u32 ul_tb_id,
const struct mlxsw_sp_ipip_entry *except)
{ … }
static void mlxsw_sp_ipip_demote_tunnel_by_ul_netdev(struct mlxsw_sp *mlxsw_sp,
struct net_device *ul_dev)
{ … }
static int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ol_dev,
unsigned long event,
struct netdev_notifier_info *info)
{ … }
static int
__mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry,
struct net_device *ul_dev,
bool *demote_this,
unsigned long event,
struct netdev_notifier_info *info)
{ … }
static int
mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *ul_dev,
unsigned long event,
struct netdev_notifier_info *info)
{ … }
int mlxsw_sp_router_nve_promote_decap(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
enum mlxsw_sp_l3proto ul_proto,
const union mlxsw_sp_l3addr *ul_sip,
u32 tunnel_index)
{ … }
void mlxsw_sp_router_nve_demote_decap(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
enum mlxsw_sp_l3proto ul_proto,
const union mlxsw_sp_l3addr *ul_sip)
{ … }
static bool mlxsw_sp_router_nve_is_decap(struct mlxsw_sp *mlxsw_sp,
u32 ul_tb_id,
enum mlxsw_sp_l3proto ul_proto,
const union mlxsw_sp_l3addr *ul_sip)
{ … }
struct mlxsw_sp_neigh_key { … };
struct mlxsw_sp_neigh_entry { … };
static const struct rhashtable_params mlxsw_sp_neigh_ht_params = …;
struct mlxsw_sp_neigh_entry *
mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
unsigned char *
mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
struct in6_addr *
mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
u64 *p_counter)
{ … }
static struct mlxsw_sp_neigh_entry *
mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
u16 rif)
{ … }
static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static int
mlxsw_sp_neigh_entry_insert(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static void
mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static bool
mlxsw_sp_neigh_counter_should_alloc(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static void
mlxsw_sp_neigh_counter_alloc(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static void
mlxsw_sp_neigh_counter_free(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static struct mlxsw_sp_neigh_entry *
mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
{ … }
static void
mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static struct mlxsw_sp_neigh_entry *
mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
{ … }
static void
mlxsw_sp_router_neighs_update_interval_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_router_neigh_ent_ipv4_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
int ent_index)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
int rec_index)
{ … }
#else
static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
int rec_index)
{
}
#endif
static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
int rec_index)
{ … }
static void mlxsw_sp_router_neigh_rec_ipv6_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
int rec_index)
{ … }
static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl, int rec_index)
{ … }
static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
{ … }
static int
__mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp,
char *rauhtd_pl,
enum mlxsw_reg_rauhtd_type type)
{ … }
static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp)
{ … }
static void
mlxsw_sp_router_neighs_update_work_schedule(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_router_neighs_update_work(struct work_struct *work)
{ … }
static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
{ … }
static void
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool removing, bool dead);
static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
{ … }
static int
mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
enum mlxsw_reg_rauht_op op)
{ … }
static int
mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
enum mlxsw_reg_rauht_op op)
{ … }
bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static void
mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool adding)
{ … }
void
mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool adding)
{ … }
struct mlxsw_sp_netevent_work { … };
static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
{ … }
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp);
static void mlxsw_sp_router_mp_hash_event_work(struct work_struct *work)
{ … }
static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp);
static void mlxsw_sp_router_update_priority_work(struct work_struct *work)
{ … }
static int mlxsw_sp_router_schedule_work(struct net *net,
struct mlxsw_sp_router *router,
struct neighbour *n,
void (*cb)(struct work_struct *))
{ … }
static bool mlxsw_sp_dev_lower_is_port(struct net_device *dev)
{ … }
static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
struct neighbour *n)
{ … }
static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
struct mlxsw_sp_neigh_rif_made_sync { … };
static void mlxsw_sp_neigh_rif_made_sync_each(struct neighbour *n, void *data)
{ … }
static int mlxsw_sp_neigh_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
enum mlxsw_sp_nexthop_type { … };
enum mlxsw_sp_nexthop_action { … };
struct mlxsw_sp_nexthop_key { … };
struct mlxsw_sp_nexthop_counter;
struct mlxsw_sp_nexthop { … };
static struct net_device *
mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh)
{ … }
enum mlxsw_sp_nexthop_group_type { … };
struct mlxsw_sp_nexthop_group_info { … };
static struct mlxsw_sp_rif *
mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi)
{ … }
struct mlxsw_sp_nexthop_group_vr_key { … };
struct mlxsw_sp_nexthop_group_vr_entry { … };
struct mlxsw_sp_nexthop_group { … };
struct mlxsw_sp_nexthop_counter { … };
static struct mlxsw_sp_nexthop_counter *
mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp)
{ … }
static void
mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_counter *nhct)
{ … }
static struct mlxsw_sp_nexthop_counter *
mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_sh_counter_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
void mlxsw_sp_nexthop_counter_disable(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static int mlxsw_sp_nexthop_counter_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh, u64 *p_counter)
{ … }
struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
struct mlxsw_sp_nexthop *nh)
{ … }
bool mlxsw_sp_nexthop_is_forward(const struct mlxsw_sp_nexthop *nh)
{ … }
unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh)
{ … }
int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index,
u32 *p_adj_size, u32 *p_adj_hash_index)
{ … }
struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh)
{ … }
bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)
{ … }
static const struct rhashtable_params mlxsw_sp_nexthop_group_vr_ht_params = …;
static struct mlxsw_sp_nexthop_group_vr_entry *
mlxsw_sp_nexthop_group_vr_entry_lookup(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_fib *fib)
{ … }
static int
mlxsw_sp_nexthop_group_vr_entry_create(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_fib *fib)
{ … }
static void
mlxsw_sp_nexthop_group_vr_entry_destroy(struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop_group_vr_entry *vr_entry)
{ … }
static int
mlxsw_sp_nexthop_group_vr_link(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_fib *fib)
{ … }
static void
mlxsw_sp_nexthop_group_vr_unlink(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_fib *fib)
{ … }
struct mlxsw_sp_nexthop_group_cmp_arg { … };
static bool
mlxsw_sp_nexthop6_group_has_nexthop(const struct mlxsw_sp_nexthop_group *nh_grp,
const struct in6_addr *gw, int ifindex,
int weight)
{ … }
static bool
mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static int
mlxsw_sp_nexthop_group_cmp(struct rhashtable_compare_arg *arg, const void *ptr)
{ … }
static u32 mlxsw_sp_nexthop_group_hash_obj(const void *data, u32 len, u32 seed)
{ … }
static u32
mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed)
{ … }
static u32
mlxsw_sp_nexthop_group_hash(const void *data, u32 len, u32 seed)
{ … }
static const struct rhashtable_params mlxsw_sp_nexthop_group_ht_params = …;
static int mlxsw_sp_nexthop_group_insert(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void mlxsw_sp_nexthop_group_remove(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop4_group_lookup(struct mlxsw_sp *mlxsw_sp,
struct fib_info *fi)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop6_group_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static const struct rhashtable_params mlxsw_sp_nexthop_ht_params = …;
static int mlxsw_sp_nexthop_insert(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_remove(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static struct mlxsw_sp_nexthop *
mlxsw_sp_nexthop_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_key key)
{ … }
static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_l3proto proto,
u16 vr_id,
u32 adj_index, u16 ecmp_size,
u32 new_adj_index,
u16 new_ecmp_size)
{ … }
static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
u32 old_adj_index, u16 old_ecmp_size)
{ … }
static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp,
u32 adj_index,
struct mlxsw_sp_nexthop *nh,
bool force, char *ratr_pl)
{ … }
int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
struct mlxsw_sp_nexthop *nh, bool force,
char *ratr_pl)
{ … }
static int __mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
u32 adj_index,
struct mlxsw_sp_nexthop *nh,
bool force, char *ratr_pl)
{ … }
static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
u32 adj_index,
struct mlxsw_sp_nexthop *nh, bool force,
char *ratr_pl)
{ … }
static int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
struct mlxsw_sp_nexthop *nh, bool force,
char *ratr_pl)
{ … }
static int
mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group_info *nhgi,
bool reallocate)
{ … }
static int
mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
struct mlxsw_sp_adj_grp_size_range { … };
static const struct mlxsw_sp_adj_grp_size_range
mlxsw_sp1_adj_grp_size_ranges[] = …;
static const struct mlxsw_sp_adj_grp_size_range
mlxsw_sp2_adj_grp_size_ranges[] = …;
static void mlxsw_sp_adj_grp_size_round_up(const struct mlxsw_sp *mlxsw_sp,
u16 *p_adj_grp_size)
{ … }
static void mlxsw_sp_adj_grp_size_round_down(const struct mlxsw_sp *mlxsw_sp,
u16 *p_adj_grp_size,
unsigned int alloc_size)
{ … }
static int mlxsw_sp_fix_adj_grp_size(struct mlxsw_sp *mlxsw_sp,
u16 *p_adj_grp_size)
{ … }
static void
mlxsw_sp_nexthop_group_normalize(struct mlxsw_sp_nexthop_group_info *nhgi)
{ … }
static void
mlxsw_sp_nexthop_group_rebalance(struct mlxsw_sp_nexthop_group_info *nhgi)
{ … }
static struct mlxsw_sp_nexthop *
mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_rt6 *mlxsw_sp_rt6);
static void
mlxsw_sp_nexthop4_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void
__mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static void
mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void
mlxsw_sp_nexthop_bucket_offload_refresh(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_nexthop *nh,
u16 bucket_index)
{ … }
static void
mlxsw_sp_nexthop_obj_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void
mlxsw_sp_nexthop_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static int
mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
bool removing)
{ … }
static int
mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{ … }
static void
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool removing, bool dead)
{ … }
static void mlxsw_sp_nexthop_crif_init(struct mlxsw_sp_nexthop *nh,
struct mlxsw_sp_crif *crif)
{ … }
static void mlxsw_sp_nexthop_crif_fini(struct mlxsw_sp_nexthop *nh)
{ … }
static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
{ … }
static void mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh,
struct mlxsw_sp_ipip_entry *ipip_entry)
{ … }
static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static bool mlxsw_sp_nexthop4_ipip_type(const struct mlxsw_sp *mlxsw_sp,
const struct fib_nh *fib_nh,
enum mlxsw_sp_ipip_type *p_ipipt)
{ … }
static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh,
const struct net_device *dev)
{ … }
static int mlxsw_sp_nexthop_type_rif_made(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_type_rif_gone(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
struct fib_nh *fib_nh)
{ … }
static void mlxsw_sp_nexthop4_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,
unsigned long event, struct fib_nh *fib_nh)
{ … }
static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
static int mlxsw_sp_nexthop_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
static int mlxsw_sp_adj_trap_entry_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_adj_trap_entry_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_nexthop_group_inc(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_nexthop_group_dec(struct mlxsw_sp *mlxsw_sp)
{ … }
static void
mlxsw_sp_nh_grp_activity_get(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_nexthop_group *nh_grp,
unsigned long *activity)
{ … }
#define MLXSW_SP_NH_GRP_ACTIVITY_UPDATE_INTERVAL …
static void
mlxsw_sp_nh_grp_activity_update(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void
mlxsw_sp_nh_grp_activity_work_schedule(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_nh_grp_activity_work(struct work_struct *work)
{ … }
static int
mlxsw_sp_nexthop_obj_single_validate(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_single_info *nh,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_nexthop_obj_group_entry_validate(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_single_info *nh,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_nexthop_obj_group_validate(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_grp_info *nh_grp,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_nexthop_obj_res_group_size_validate(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_res_table_info *nh_res_table,
struct netlink_ext_ack *extack)
{ … }
static int
mlxsw_sp_nexthop_obj_res_group_validate(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_res_table_info *nh_res_table,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_nexthop_obj_validate(struct mlxsw_sp *mlxsw_sp,
unsigned long event,
struct nh_notifier_info *info)
{ … }
static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_info *info)
{ … }
static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static int
mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
struct nh_notifier_single_info *nh_obj, int weight)
{ … }
static void mlxsw_sp_nexthop_obj_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static int
mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct nh_notifier_info *info)
{ … }
static void
mlxsw_sp_nexthop_obj_group_info_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop_obj_group_create(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static void
mlxsw_sp_nexthop_obj_group_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop_obj_group_lookup(struct mlxsw_sp *mlxsw_sp, u32 id)
{ … }
static int mlxsw_sp_nexthop_obj_group_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static int
mlxsw_sp_nexthop_obj_group_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop_group *old_nh_grp,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_nexthop_obj_res_group_pre(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static int mlxsw_sp_nexthop_obj_new(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static void mlxsw_sp_nexthop_obj_del(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static int mlxsw_sp_nexthop_obj_bucket_query(struct mlxsw_sp *mlxsw_sp,
u32 adj_index, char *ratr_pl)
{ … }
static int mlxsw_sp_nexthop_obj_bucket_compare(char *ratr_pl, char *ratr_pl_new)
{ … }
static int
mlxsw_sp_nexthop_obj_bucket_adj_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh,
struct nh_notifier_info *info)
{ … }
static int mlxsw_sp_nexthop_obj_bucket_replace(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static void
mlxsw_sp_nexthop_obj_mp_hw_stats_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group_info *nhgi,
struct nh_notifier_grp_hw_stats_info *info)
{ … }
static void
mlxsw_sp_nexthop_obj_res_hw_stats_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group_info *nhgi,
struct nh_notifier_grp_hw_stats_info *info)
{ … }
static void mlxsw_sp_nexthop_obj_hw_stats_get(struct mlxsw_sp *mlxsw_sp,
struct nh_notifier_info *info)
{ … }
static int mlxsw_sp_nexthop_obj_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
struct fib_info *fi)
{ … }
static int
mlxsw_sp_nexthop4_group_info_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static void
mlxsw_sp_nexthop4_group_info_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
{ … }
static void
mlxsw_sp_nexthop4_group_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static int mlxsw_sp_nexthop4_group_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
struct fib_info *fi)
{ … }
static void mlxsw_sp_nexthop4_group_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static bool
mlxsw_sp_fib4_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static bool
mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static struct mlxsw_sp_nexthop *
mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
const struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
{ … }
static void
mlxsw_sp_fib4_offload_failed_flag_set(struct mlxsw_sp *mlxsw_sp,
struct fib_entry_notifier_info *fen_info)
{ … }
static void
mlxsw_sp_fib4_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib4_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void
mlxsw_sp_fib6_offload_failed_flag_set(struct mlxsw_sp *mlxsw_sp,
struct fib6_info **rt_arr,
unsigned int nrt6)
{ … }
#else
static void
mlxsw_sp_fib6_offload_failed_flag_set(struct mlxsw_sp *mlxsw_sp,
struct fib6_info **rt_arr,
unsigned int nrt6)
{
}
#endif
#if IS_ENABLED(CONFIG_IPV6)
static void
mlxsw_sp_fib6_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
#else
static void
mlxsw_sp_fib6_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{
}
#endif
#if IS_ENABLED(CONFIG_IPV6)
static void
mlxsw_sp_fib6_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
#else
static void
mlxsw_sp_fib6_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{
}
#endif
static void
mlxsw_sp_fib_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib_entry_hw_flags_refresh(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static void
mlxsw_sp_fib_entry_ralue_pack(char *ralue_pl,
const struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op_local(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op_trap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op_blackhole(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int
mlxsw_sp_fib_entry_op_unreachable(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int
mlxsw_sp_fib_entry_op_ipip_decap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op_nve_decap(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
{ … }
static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static int mlxsw_sp_fib_entry_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static int
mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
const struct fib_entry_notifier_info *fen_info,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib_entry_type_unset(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib4_entry_type_unset(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib4_entry *fib4_entry)
{ … }
static struct mlxsw_sp_fib4_entry *
mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node,
const struct fib_entry_notifier_info *fen_info)
{ … }
static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib4_entry *fib4_entry)
{ … }
static struct mlxsw_sp_fib4_entry *
mlxsw_sp_fib4_entry_lookup(struct mlxsw_sp *mlxsw_sp,
const struct fib_entry_notifier_info *fen_info)
{ … }
static const struct rhashtable_params mlxsw_sp_fib_ht_params = …;
static int mlxsw_sp_fib_node_insert(struct mlxsw_sp_fib *fib,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static void mlxsw_sp_fib_node_remove(struct mlxsw_sp_fib *fib,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static struct mlxsw_sp_fib_node *
mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
size_t addr_len, unsigned char prefix_len)
{ … }
static struct mlxsw_sp_fib_node *
mlxsw_sp_fib_node_create(struct mlxsw_sp_fib *fib, const void *addr,
size_t addr_len, unsigned char prefix_len)
{ … }
static void mlxsw_sp_fib_node_destroy(struct mlxsw_sp_fib_node *fib_node)
{ … }
static int mlxsw_sp_fib_lpm_tree_link(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static int mlxsw_sp_fib_node_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node,
struct mlxsw_sp_fib *fib)
{ … }
static void mlxsw_sp_fib_node_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static struct mlxsw_sp_fib_node *
mlxsw_sp_fib_node_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id, const void *addr,
size_t addr_len, unsigned char prefix_len,
enum mlxsw_sp_l3proto proto)
{ … }
static void mlxsw_sp_fib_node_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static int mlxsw_sp_fib_node_entry_link(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static void
mlxsw_sp_fib_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static bool mlxsw_sp_fib4_allow_replace(struct mlxsw_sp_fib4_entry *fib4_entry)
{ … }
static int
mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
const struct fib_entry_notifier_info *fen_info)
{ … }
static void mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp,
struct fib_entry_notifier_info *fen_info)
{ … }
static bool mlxsw_sp_fib6_rt_should_ignore(const struct fib6_info *rt)
{ … }
static struct mlxsw_sp_rt6 *mlxsw_sp_rt6_create(struct fib6_info *rt)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void mlxsw_sp_rt6_release(struct fib6_info *rt)
{ … }
#else
static void mlxsw_sp_rt6_release(struct fib6_info *rt)
{
}
#endif
static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
{ … }
static struct fib6_info *
mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static struct mlxsw_sp_rt6 *
mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,
const struct fib6_info *rt)
{ … }
static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp,
const struct fib6_info *rt,
enum mlxsw_sp_ipip_type *ret)
{ … }
static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
const struct fib6_info *rt)
{ … }
static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{ … }
static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
const struct fib6_info *rt)
{ … }
static int
mlxsw_sp_nexthop6_group_info_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static void
mlxsw_sp_nexthop6_group_info_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static void
mlxsw_sp_nexthop6_group_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
{ … }
static int mlxsw_sp_nexthop6_group_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static void mlxsw_sp_nexthop6_group_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{ … }
static int
mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static int
mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry,
struct fib6_info **rt_arr, unsigned int nrt6)
{ … }
static void
mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry,
struct fib6_info **rt_arr, unsigned int nrt6)
{ … }
static int
mlxsw_sp_fib6_entry_type_set_local(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
const struct fib6_info *rt)
{ … }
static int mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
const struct fib6_info *rt)
{ … }
static void
mlxsw_sp_fib6_entry_rt_destroy_all(struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static struct mlxsw_sp_fib6_entry *
mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node,
struct fib6_info **rt_arr, unsigned int nrt6)
{ … }
static void
mlxsw_sp_fib6_entry_type_unset(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static void mlxsw_sp_fib6_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static struct mlxsw_sp_fib6_entry *
mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,
const struct fib6_info *rt)
{ … }
static bool mlxsw_sp_fib6_allow_replace(struct mlxsw_sp_fib6_entry *fib6_entry)
{ … }
static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
struct fib6_info **rt_arr,
unsigned int nrt6)
{ … }
static int mlxsw_sp_router_fib6_append(struct mlxsw_sp *mlxsw_sp,
struct fib6_info **rt_arr,
unsigned int nrt6)
{ … }
static void mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp,
struct fib6_info **rt_arr,
unsigned int nrt6)
{ … }
static struct mlxsw_sp_mr_table *
mlxsw_sp_router_fibmr_family_to_table(struct mlxsw_sp_vr *vr, int family)
{ … }
static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
struct mfc_entry_notifier_info *men_info,
bool replace)
{ … }
static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
struct mfc_entry_notifier_info *men_info)
{ … }
static int
mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
struct vif_entry_notifier_info *ven_info)
{ … }
static void
mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
struct vif_entry_notifier_info *ven_info)
{ … }
static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static void mlxsw_sp_fib6_node_flush(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static void mlxsw_sp_fib_node_flush(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node)
{ … }
static void mlxsw_sp_vr_fib_flush(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_vr *vr,
enum mlxsw_sp_l3proto proto)
{ … }
static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
{ … }
struct mlxsw_sp_fib6_event_work { … };
struct mlxsw_sp_fib_event_work { … };
static int
mlxsw_sp_router_fib6_work_init(struct mlxsw_sp_fib6_event_work *fib6_work,
struct fib6_entry_notifier_info *fen6_info)
{ … }
static void
mlxsw_sp_router_fib6_work_fini(struct mlxsw_sp_fib6_event_work *fib6_work)
{ … }
static void mlxsw_sp_router_fib4_event_work(struct work_struct *work)
{ … }
static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
{ … }
static void mlxsw_sp_router_fibmr_event_work(struct work_struct *work)
{ … }
static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work,
struct fib_notifier_info *info)
{ … }
static int mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
struct fib_notifier_info *info)
{ … }
static void
mlxsw_sp_router_fibmr_event(struct mlxsw_sp_fib_event_work *fib_work,
struct fib_notifier_info *info)
{ … }
static int mlxsw_sp_router_fib_rule_event(unsigned long event,
struct fib_notifier_info *info,
struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev)
{ … }
bool mlxsw_sp_rif_exists(struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev)
{ … }
u16 mlxsw_sp_rif_vid(struct mlxsw_sp *mlxsw_sp, const struct net_device *dev)
{ … }
static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif)
{ … }
static int mlxsw_sp_router_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{ … }
static bool __mlxsw_sp_dev_addr_list_empty(const struct net_device *dev)
{ … }
static bool mlxsw_sp_dev_addr_list_empty(const struct net_device *dev)
{ … }
static bool
mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *rif, struct net_device *dev,
unsigned long event)
{ … }
static enum mlxsw_sp_rif_type
mlxsw_sp_dev_rif_type(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev)
{ … }
static int mlxsw_sp_rif_index_alloc(struct mlxsw_sp *mlxsw_sp, u16 *p_rif_index,
u8 rif_entries)
{ … }
static void mlxsw_sp_rif_index_free(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
u8 rif_entries)
{ … }
static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index,
u16 vr_id,
struct mlxsw_sp_crif *crif)
{ … }
static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif)
{ … }
struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
u16 rif_index)
{ … }
u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif)
{ … }
u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
{ … }
u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
{ … }
u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
{ … }
static bool
mlxsw_sp_router_port_l3_stats_enabled(struct mlxsw_sp_rif *rif)
{ … }
static int
mlxsw_sp_router_port_l3_stats_enable(struct mlxsw_sp_rif *rif)
{ … }
static void
mlxsw_sp_router_port_l3_stats_disable(struct mlxsw_sp_rif *rif)
{ … }
static void
mlxsw_sp_router_port_l3_stats_report_used(struct mlxsw_sp_rif *rif,
struct netdev_notifier_offload_xstats_info *info)
{ … }
static int
mlxsw_sp_router_port_l3_stats_fetch(struct mlxsw_sp_rif *rif,
struct rtnl_hw_stats64 *p_stats)
{ … }
static int
mlxsw_sp_router_port_l3_stats_report_delta(struct mlxsw_sp_rif *rif,
struct netdev_notifier_offload_xstats_info *info)
{ … }
struct mlxsw_sp_router_hwstats_notify_work { … };
static void mlxsw_sp_router_hwstats_notify_work(struct work_struct *work)
{ … }
static void
mlxsw_sp_router_hwstats_notify_schedule(struct net_device *dev)
{ … }
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
{ … }
bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif)
{ … }
bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif,
const struct net_device *dev)
{ … }
static void mlxsw_sp_rif_push_l3_stats(struct mlxsw_sp_rif *rif)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
{ … }
void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev)
{ … }
static void mlxsw_sp_rif_destroy_vlan_upper(struct mlxsw_sp *mlxsw_sp,
struct net_device *br_dev,
u16 vid)
{ … }
static int mlxsw_sp_inetaddr_bridge_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *l3_dev,
int lower_pvid,
unsigned long event,
struct netlink_ext_ack *extack);
int mlxsw_sp_router_bridge_vlan_add(struct mlxsw_sp *mlxsw_sp,
struct net_device *br_dev,
u16 new_vid, bool is_pvid,
struct netlink_ext_ack *extack)
{ … }
static void
mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
{ … }
static struct mlxsw_sp_rif_subport *
mlxsw_sp_rif_subport_rif(const struct mlxsw_sp_rif *rif)
{ … }
int mlxsw_sp_rif_subport_port(const struct mlxsw_sp_rif *rif,
u16 *port, bool *is_lag)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_rif_subport_get(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_subport_put(struct mlxsw_sp_rif *rif)
{ … }
static int mlxsw_sp_rif_mac_profile_index_alloc(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif_mac_profile *profile,
struct netlink_ext_ack *extack)
{ … }
static struct mlxsw_sp_rif_mac_profile *
mlxsw_sp_rif_mac_profile_index_free(struct mlxsw_sp *mlxsw_sp, u8 mac_profile)
{ … }
static struct mlxsw_sp_rif_mac_profile *
mlxsw_sp_rif_mac_profile_alloc(const char *mac)
{ … }
static struct mlxsw_sp_rif_mac_profile *
mlxsw_sp_rif_mac_profile_find(const struct mlxsw_sp *mlxsw_sp, const char *mac)
{ … }
static u64 mlxsw_sp_rif_mac_profiles_occ_get(void *priv)
{ … }
static u64 mlxsw_sp_rifs_occ_get(void *priv)
{ … }
static struct mlxsw_sp_rif_mac_profile *
mlxsw_sp_rif_mac_profile_create(struct mlxsw_sp *mlxsw_sp, const char *mac,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_mac_profile_destroy(struct mlxsw_sp *mlxsw_sp,
u8 mac_profile)
{ … }
static int mlxsw_sp_rif_mac_profile_get(struct mlxsw_sp *mlxsw_sp,
const char *mac, u8 *p_mac_profile,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_mac_profile_put(struct mlxsw_sp *mlxsw_sp,
u8 mac_profile)
{ … }
static bool mlxsw_sp_rif_mac_profile_is_shared(const struct mlxsw_sp_rif *rif)
{ … }
static int mlxsw_sp_rif_mac_profile_edit(struct mlxsw_sp_rif *rif,
const char *new_mac)
{ … }
static int
mlxsw_sp_rif_mac_profile_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif,
const char *new_mac,
struct netlink_ext_ack *extack)
{ … }
static int
__mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
struct net_device *l3_dev,
struct netlink_ext_ack *extack)
{ … }
static void
__mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
{ … }
static int
mlxsw_sp_port_vlan_router_join_existing(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
struct net_device *l3_dev,
struct netlink_ext_ack *extack)
{ … }
void
mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
{ … }
static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
struct net_device *port_dev,
unsigned long event, u16 vid,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
unsigned long event, bool nomaster,
struct netlink_ext_ack *extack)
{ … }
static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
struct net_device *lag_dev,
unsigned long event, u16 vid,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
unsigned long event, bool nomaster,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_inetaddr_bridge_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *l3_dev,
int lower_pvid,
unsigned long event,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *vlan_dev,
unsigned long event, bool nomaster,
struct netlink_ext_ack *extack)
{ … }
static bool mlxsw_sp_rif_macvlan_is_vrrp4(const u8 *mac)
{ … }
static bool mlxsw_sp_rif_macvlan_is_vrrp6(const u8 *mac)
{ … }
static int mlxsw_sp_rif_vrrp_op(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
const u8 *mac, bool adding)
{ … }
static int mlxsw_sp_rif_macvlan_add(struct mlxsw_sp *mlxsw_sp,
const struct net_device *macvlan_dev,
struct netlink_ext_ack *extack)
{ … }
static void __mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp,
const struct net_device *macvlan_dev)
{ … }
void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp,
const struct net_device *macvlan_dev)
{ … }
static int mlxsw_sp_inetaddr_macvlan_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *macvlan_dev,
unsigned long event,
struct netlink_ext_ack *extack)
{ … }
static int __mlxsw_sp_inetaddr_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev,
unsigned long event, bool nomaster,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_inetaddr_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
struct mlxsw_sp_inet6addr_event_work { … };
static void mlxsw_sp_inet6addr_event_work(struct work_struct *work)
{ … }
static int mlxsw_sp_inet6addr_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
const char *mac, int mtu, u8 mac_profile)
{ … }
static int
mlxsw_sp_router_port_change_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static int mlxsw_sp_router_port_pre_changeaddr_event(struct mlxsw_sp_rif *rif,
struct netdev_notifier_pre_changeaddr_info *info)
{ … }
static bool mlxsw_sp_router_netdevice_interesting(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev)
{ … }
static struct mlxsw_sp_crif *
mlxsw_sp_crif_register(struct mlxsw_sp_router *router, struct net_device *dev)
{ … }
static void mlxsw_sp_crif_unregister(struct mlxsw_sp_router *router,
struct mlxsw_sp_crif *crif)
{ … }
static int mlxsw_sp_netdevice_register(struct mlxsw_sp_router *router,
struct net_device *dev)
{ … }
static void mlxsw_sp_netdevice_unregister(struct mlxsw_sp_router *router,
struct net_device *dev)
{ … }
static bool mlxsw_sp_is_offload_xstats_event(unsigned long event)
{ … }
static int
mlxsw_sp_router_port_offload_xstats_cmd(struct mlxsw_sp_rif *rif,
unsigned long event,
struct netdev_notifier_offload_xstats_info *info)
{ … }
static int
mlxsw_sp_netdevice_offload_xstats_cmd(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev,
unsigned long event,
struct netdev_notifier_offload_xstats_info *info)
{ … }
static bool mlxsw_sp_is_router_event(unsigned long event)
{ … }
static int mlxsw_sp_netdevice_router_port_event(struct net_device *dev,
unsigned long event, void *ptr)
{ … }
static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp,
struct net_device *l3_dev,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
struct net_device *l3_dev)
{ … }
static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr)
{ … }
static int
mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
struct netdev_notifier_changeupper_info *info)
{ … }
struct mlxsw_sp_router_replay_inetaddr_up { … };
static int mlxsw_sp_router_replay_inetaddr_up(struct net_device *dev,
struct netdev_nested_priv *priv)
{ … }
static int mlxsw_sp_router_unreplay_inetaddr_up(struct net_device *dev,
struct netdev_nested_priv *priv)
{ … }
int mlxsw_sp_netdevice_enslavement_replay(struct mlxsw_sp *mlxsw_sp,
struct net_device *upper_dev,
struct netlink_ext_ack *extack)
{ … }
void mlxsw_sp_netdevice_deslavement_replay(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev)
{ … }
static int
mlxsw_sp_port_vid_router_join_existing(struct mlxsw_sp_port *mlxsw_sp_port,
u16 vid, struct net_device *dev,
struct netlink_ext_ack *extack)
{ … }
static void
mlxsw_sp_port_vid_router_leave(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
struct net_device *dev)
{ … }
static int __mlxsw_sp_router_port_join_lag(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *lag_dev,
struct netlink_ext_ack *extack)
{ … }
static void
__mlxsw_sp_router_port_leave_lag(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *lag_dev)
{ … }
int mlxsw_sp_router_port_join_lag(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *lag_dev,
struct netlink_ext_ack *extack)
{ … }
void mlxsw_sp_router_port_leave_lag(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *lag_dev)
{ … }
static int mlxsw_sp_router_netdevice_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
struct mlxsw_sp_macvlan_replay { … };
static int mlxsw_sp_macvlan_replay_upper(struct net_device *dev,
struct netdev_nested_priv *priv)
{ … }
static int mlxsw_sp_macvlan_replay(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev,
struct netdev_nested_priv *priv)
{ … }
static int mlxsw_sp_rif_macvlan_flush(struct mlxsw_sp_rif *rif)
{ … }
static void mlxsw_sp_rif_subport_setup(struct mlxsw_sp_rif *rif,
const struct mlxsw_sp_rif_params *params)
{ … }
static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable)
{ … }
static int mlxsw_sp_rif_subport_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif)
{ … }
static struct mlxsw_sp_fid *
mlxsw_sp_rif_subport_fid_get(struct mlxsw_sp_rif *rif,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_subport_ops = …;
static int mlxsw_sp_rif_fid_op(struct mlxsw_sp_rif *rif, u16 fid, bool enable)
{ … }
u16 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif)
{ … }
static struct mlxsw_sp_fid *
mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = …;
static struct mlxsw_sp_fid *
mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
const struct mlxsw_sp_rif_params *params,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
{ … }
static int mlxsw_sp_rif_vlan_op(struct mlxsw_sp_rif *rif, u16 vid, u16 efid,
bool enable)
{ … }
static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif, u16 efid,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif)
{ … }
static int mlxsw_sp1_rif_vlan_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp1_rif_vlan_ops = …;
static int mlxsw_sp2_rif_vlan_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp2_rif_vlan_ops = …;
static struct mlxsw_sp_rif_ipip_lb *
mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif)
{ … }
static void
mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif,
const struct mlxsw_sp_rif_params *params)
{ … }
static int
mlxsw_sp1_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp1_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp1_rif_ipip_lb_ops = …;
static const struct mlxsw_sp_rif_ops *mlxsw_sp1_rif_ops_arr[] = …;
static int
mlxsw_sp_rif_ipip_lb_ul_rif_op(struct mlxsw_sp_rif *ul_rif, bool enable)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
struct mlxsw_sp_crif *ul_crif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_ul_rif_destroy(struct mlxsw_sp_rif *ul_rif)
{ … }
static struct mlxsw_sp_rif *
mlxsw_sp_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
struct mlxsw_sp_crif *ul_crif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_ul_rif_put(struct mlxsw_sp_rif *ul_rif)
{ … }
int mlxsw_sp_router_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
u16 *ul_rif_index)
{ … }
void mlxsw_sp_router_ul_rif_put(struct mlxsw_sp *mlxsw_sp, u16 ul_rif_index)
{ … }
static int
mlxsw_sp2_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp2_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif)
{ … }
static const struct mlxsw_sp_rif_ops mlxsw_sp2_rif_ipip_lb_ops = …;
static const struct mlxsw_sp_rif_ops *mlxsw_sp2_rif_ops_arr[] = …;
static int mlxsw_sp_rifs_table_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_rifs_table_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static int
mlxsw_sp_ipip_config_tigcr(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp1_ipips_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp2_ipips_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)
{ … }
#ifdef CONFIG_IP_ROUTE_MULTIPATH
struct mlxsw_sp_mp_hash_config { … };
#define MLXSW_SP_MP_HASH_HEADER_SET(_headers, _header) …
#define MLXSW_SP_MP_HASH_FIELD_SET(_fields, _field) …
#define MLXSW_SP_MP_HASH_FIELD_RANGE_SET(_fields, _field, _nr) …
static void mlxsw_sp_mp_hash_inner_l3(struct mlxsw_sp_mp_hash_config *config)
{ … }
static void mlxsw_sp_mp4_hash_outer_addr(struct mlxsw_sp_mp_hash_config *config)
{ … }
static void
mlxsw_sp_mp_hash_inner_custom(struct mlxsw_sp_mp_hash_config *config,
u32 hash_fields)
{ … }
static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mp_hash_config *config)
{ … }
static void mlxsw_sp_mp6_hash_outer_addr(struct mlxsw_sp_mp_hash_config *config)
{ … }
static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mp_hash_config *config)
{ … }
static int mlxsw_sp_mp_hash_parsing_depth_adjust(struct mlxsw_sp *mlxsw_sp,
bool old_inc_parsing_depth,
bool new_inc_parsing_depth)
{ … }
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
#else
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
{
return 0;
}
static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
{
}
#endif
static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp_lb_rif_init(struct mlxsw_sp *mlxsw_sp,
struct netlink_ext_ack *extack)
{ … }
static void mlxsw_sp_lb_rif_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp1_router_init(struct mlxsw_sp *mlxsw_sp)
{ … }
const struct mlxsw_sp_router_ops mlxsw_sp1_router_ops = …;
static int mlxsw_sp2_router_init(struct mlxsw_sp *mlxsw_sp)
{ … }
const struct mlxsw_sp_router_ops mlxsw_sp2_router_ops = …;
int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
struct netlink_ext_ack *extack)
{ … }
void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
{ … }