Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2e4a219 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-Add-support-for-offloading-IPv4-multicast-routes'



Jiri Pirko says:

====================
mlxsw: Add support for offloading IPv4 multicast routes

Yotam says:

This patch-set introduces offloading of the kernel IPv4 multicast router
logic in the Spectrum driver.

The first patch makes the Spectrum driver ignore FIB notifications that are
not of address family IPv4 or IPv6. This is needed in order to prevent
crashes while the next patches introduce the RTNL_FAMILY_IPMR FIB
notifications.

Patches 2-5 update ipmr to use the FIB notification chain for both MFC and
VIF notifications, and patches 8-12 update the Spectrum driver to register
to these notifications and offload the routes.

Similarly to IPv4 and IPv6, any failure will trigger the abort mechanism
which is updated in this patch-set to eject multicast route tables too.

At this stage, the following limitations apply:
 - A multicast MFC route will be offloaded by the driver if all the output
   interfaces are Spectrum router interfaces (RIFs). In any other case
   (which includes pimreg device, tunnel devices and management ports) the
   route will be trapped to the CPU and the packets will be forwarded by
   software.
 - ipmr proxy routes are not supported and will trigger the abort
   mechanism.
 - The MFC TTL values are currently treated as boolean: if the value is
   different than 255, the traffic is forwarded to the interface and if the
   value is 255 it is not forwarded. Dropping packets based on their TTL isn't
   currently supported.

To allow users to have visibility on which of the routes are offloaded and
which are not, patch 6 introduces a per-route offload indication similar to
IPv4 and IPv6 routes which is sent to the user via the RTNetlink interface.

The Spectrum driver multicast router offloading support, which is
introduced in patches 8 and 9, is divided into two parts:
 - The hardware logic which abstracts the Spectrum hardware and provides a
   simple API for the upper levels.
 - The offloading logic which gets the MFC and VIF notifications from the
   kernel and updates the hardware using the hardware logic part.

Finally, the last patch makes the Spectrum router logic not ignore the
multicast FIB notifications and call the corresponding functions in the
multicast router offloading logic.

---
v2->v3:
 - Move the ipmr_rule_default function definition to be inside the already
   existing CONFIG_IP_MROUTE_MULTIPLE_TABLES ifdef block (patch 6)
 - Remove double =0 initialization in spectrum_mr.c (patch 7)
 - Fix route4 allocation size (patch 7)
v1->v2:
 - Add comments for struct fields in mroute.h
 - Take the mrt_lock while dumping VIFs in the fib_notifier dump callback
 - Update the MFC lastuse field too
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1ca94d79 664375e9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -17,7 +17,8 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
				   spectrum_kvdl.o spectrum_acl_tcam.o \
				   spectrum_acl.o spectrum_flower.o \
				   spectrum_cnt.o spectrum_fid.o \
				   spectrum_ipip.o spectrum_acl_flex_actions.o
				   spectrum_ipip.o spectrum_acl_flex_actions.o \
				   spectrum_mr.o spectrum_mr_tcam.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB)	+= spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
obj-$(CONFIG_MLXSW_MINIMAL)	+= mlxsw_minimal.o
+2 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ struct mlxsw_sp_port_mall_tc_entry {
struct mlxsw_sp_sb;
struct mlxsw_sp_bridge;
struct mlxsw_sp_router;
struct mlxsw_sp_mr;
struct mlxsw_sp_acl;
struct mlxsw_sp_counter_pool;
struct mlxsw_sp_fid_core;
@@ -153,6 +154,7 @@ struct mlxsw_sp {
	struct mlxsw_sp_sb *sb;
	struct mlxsw_sp_bridge *bridge;
	struct mlxsw_sp_router *router;
	struct mlxsw_sp_mr *mr;
	struct mlxsw_afa *afa;
	struct mlxsw_sp_acl *acl;
	struct mlxsw_sp_fid_core *fid_core;
+1014 −0

File added.

Preview size limit exceeded, changes collapsed.

+133 −0
Original line number Diff line number Diff line
/*
 * drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.h
 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
 * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _MLXSW_SPECTRUM_MCROUTER_H
#define _MLXSW_SPECTRUM_MCROUTER_H

#include <linux/mroute.h>
#include "spectrum_router.h"
#include "spectrum.h"

enum mlxsw_sp_mr_route_action {
	MLXSW_SP_MR_ROUTE_ACTION_FORWARD,
	MLXSW_SP_MR_ROUTE_ACTION_TRAP,
};

enum mlxsw_sp_mr_route_prio {
	MLXSW_SP_MR_ROUTE_PRIO_SG,
	MLXSW_SP_MR_ROUTE_PRIO_STARG,
	MLXSW_SP_MR_ROUTE_PRIO_CATCHALL,
	__MLXSW_SP_MR_ROUTE_PRIO_MAX
};

#define MLXSW_SP_MR_ROUTE_PRIO_MAX (__MLXSW_SP_MR_ROUTE_PRIO_MAX - 1)

struct mlxsw_sp_mr_route_key {
	int vrid;
	enum mlxsw_sp_l3proto proto;
	union mlxsw_sp_l3addr group;
	union mlxsw_sp_l3addr group_mask;
	union mlxsw_sp_l3addr source;
	union mlxsw_sp_l3addr source_mask;
};

struct mlxsw_sp_mr_route_info {
	enum mlxsw_sp_mr_route_action route_action;
	u16 irif_index;
	u16 *erif_indices;
	size_t erif_num;
	u16 min_mtu;
};

struct mlxsw_sp_mr_route_params {
	struct mlxsw_sp_mr_route_key key;
	struct mlxsw_sp_mr_route_info value;
	enum mlxsw_sp_mr_route_prio prio;
};

struct mlxsw_sp_mr_ops {
	int priv_size;
	int route_priv_size;
	int (*init)(struct mlxsw_sp *mlxsw_sp, void *priv);
	int (*route_create)(struct mlxsw_sp *mlxsw_sp, void *priv,
			    void *route_priv,
			    struct mlxsw_sp_mr_route_params *route_params);
	int (*route_update)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
			    struct mlxsw_sp_mr_route_info *route_info);
	int (*route_stats)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
			   u64 *packets, u64 *bytes);
	int (*route_action_update)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
				   enum mlxsw_sp_mr_route_action route_action);
	int (*route_min_mtu_update)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
				    u16 min_mtu);
	int (*route_irif_update)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
				 u16 irif_index);
	int (*route_erif_add)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
			      u16 erif_index);
	int (*route_erif_del)(struct mlxsw_sp *mlxsw_sp, void *route_priv,
			      u16 erif_index);
	void (*route_destroy)(struct mlxsw_sp *mlxsw_sp, void *priv,
			      void *route_priv);
	void (*fini)(void *priv);
};

struct mlxsw_sp_mr;
struct mlxsw_sp_mr_table;

int mlxsw_sp_mr_init(struct mlxsw_sp *mlxsw_sp,
		     const struct mlxsw_sp_mr_ops *mr_ops);
void mlxsw_sp_mr_fini(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table,
			   struct mfc_cache *mfc, bool replace);
void mlxsw_sp_mr_route4_del(struct mlxsw_sp_mr_table *mr_table,
			    struct mfc_cache *mfc);
int mlxsw_sp_mr_vif_add(struct mlxsw_sp_mr_table *mr_table,
			struct net_device *dev, vifi_t vif_index,
			unsigned long vif_flags,
			const struct mlxsw_sp_rif *rif);
void mlxsw_sp_mr_vif_del(struct mlxsw_sp_mr_table *mr_table, vifi_t vif_index);
int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table,
			const struct mlxsw_sp_rif *rif);
void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table,
			 const struct mlxsw_sp_rif *rif);
void mlxsw_sp_mr_rif_mtu_update(struct mlxsw_sp_mr_table *mr_table,
				const struct mlxsw_sp_rif *rif, int mtu);
struct mlxsw_sp_mr_table *mlxsw_sp_mr_table_create(struct mlxsw_sp *mlxsw_sp,
						   u32 tb_id,
						   enum mlxsw_sp_l3proto proto);
void mlxsw_sp_mr_table_destroy(struct mlxsw_sp_mr_table *mr_table);
void mlxsw_sp_mr_table_flush(struct mlxsw_sp_mr_table *mr_table);
bool mlxsw_sp_mr_table_empty(const struct mlxsw_sp_mr_table *mr_table);

#endif
+828 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading