2017-03-28 22:24:15 +07:00
|
|
|
/*
|
|
|
|
* drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
|
|
|
|
* Copyright (c) 2017 Mellanox Technologies. All rights reserved.
|
|
|
|
* Copyright (c) 2017 Arkadi Sharshevsky <arkadis@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_ROUTER_H_
|
|
|
|
#define _MLXSW_ROUTER_H_
|
|
|
|
|
|
|
|
#include "spectrum.h"
|
2017-09-03 04:49:19 +07:00
|
|
|
#include "reg.h"
|
2017-03-28 22:24:15 +07:00
|
|
|
|
2017-09-03 04:49:16 +07:00
|
|
|
enum mlxsw_sp_l3proto {
|
|
|
|
MLXSW_SP_L3_PROTO_IPV4,
|
|
|
|
MLXSW_SP_L3_PROTO_IPV6,
|
2018-03-26 19:01:40 +07:00
|
|
|
#define MLXSW_SP_L3_PROTO_MAX (MLXSW_SP_L3_PROTO_IPV6 + 1)
|
2017-09-03 04:49:16 +07:00
|
|
|
};
|
|
|
|
|
2017-09-03 04:49:19 +07:00
|
|
|
union mlxsw_sp_l3addr {
|
|
|
|
__be32 addr4;
|
|
|
|
struct in6_addr addr6;
|
|
|
|
};
|
|
|
|
|
2017-09-03 04:49:28 +07:00
|
|
|
struct mlxsw_sp_rif_ipip_lb;
|
2017-09-03 04:49:19 +07:00
|
|
|
struct mlxsw_sp_rif_ipip_lb_config {
|
|
|
|
enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
|
|
|
|
u32 okey;
|
|
|
|
enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */
|
|
|
|
union mlxsw_sp_l3addr saddr;
|
|
|
|
};
|
|
|
|
|
2017-03-28 22:24:15 +07:00
|
|
|
enum mlxsw_sp_rif_counter_dir {
|
|
|
|
MLXSW_SP_RIF_COUNTER_INGRESS,
|
|
|
|
MLXSW_SP_RIF_COUNTER_EGRESS,
|
|
|
|
};
|
|
|
|
|
2017-08-24 13:40:04 +07:00
|
|
|
struct mlxsw_sp_neigh_entry;
|
2017-09-25 15:32:25 +07:00
|
|
|
struct mlxsw_sp_nexthop;
|
2017-11-03 16:03:38 +07:00
|
|
|
struct mlxsw_sp_ipip_entry;
|
2017-08-24 13:40:04 +07:00
|
|
|
|
2017-05-17 00:38:27 +07:00
|
|
|
struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
|
|
|
|
u16 rif_index);
|
2017-03-28 22:24:16 +07:00
|
|
|
u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
|
2017-09-03 04:49:28 +07:00
|
|
|
u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif);
|
|
|
|
u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
|
2017-11-03 16:03:42 +07:00
|
|
|
u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev);
|
2017-03-28 22:24:16 +07:00
|
|
|
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
|
2017-10-09 16:15:33 +07:00
|
|
|
u8 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp);
|
2017-09-19 15:00:19 +07:00
|
|
|
const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif);
|
2017-03-28 22:24:15 +07:00
|
|
|
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);
|
|
|
|
void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_rif *rif,
|
|
|
|
enum mlxsw_sp_rif_counter_dir dir);
|
|
|
|
int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_rif *rif,
|
|
|
|
enum mlxsw_sp_rif_counter_dir dir);
|
2017-08-24 13:40:04 +07:00
|
|
|
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);
|
2017-08-31 22:59:15 +07:00
|
|
|
struct in6_addr *
|
|
|
|
mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
|
2017-08-24 13:40:04 +07:00
|
|
|
|
|
|
|
#define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) \
|
|
|
|
for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry; \
|
|
|
|
neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry))
|
2017-08-24 13:40:08 +07:00
|
|
|
int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_neigh_entry *neigh_entry,
|
|
|
|
u64 *p_counter);
|
2017-08-24 13:40:10 +07:00
|
|
|
void
|
|
|
|
mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_neigh_entry *neigh_entry,
|
|
|
|
bool adding);
|
2017-08-31 22:59:13 +07:00
|
|
|
bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
|
2017-11-03 16:03:38 +07:00
|
|
|
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);
|
mlxsw: spectrum_router: Onload conflicting tunnels
The approach for offloading IP tunnels implemented currently by mlxsw
doesn't allow two tunnels that have the same local IP address in the
same (underlay) VRF. Previously, offloads were introduced on demand as
encap routes were formed. When such a route was created that would cause
offload of a conflicting tunnel, mlxsw_sp_ipip_entry_create() would
detect it and return -EEXIST, which would propagate up and cause FIB
abort.
Now however IPIP entries are created as soon as an offloadable netdevice
is created, and the failure prevents creation of such device.
Furthermore, if the driver is installed at the point where such
conflicting tunnels exist, the failure actually prevents successful
modprobe.
Furthermore, follow-up patches implement handling of NETDEV_CHANGE due
to the local address change. However, NETDEV_CHANGE can't be vetoed. The
failure merely means that the offloads weren't updated, but the change
in Linux configuration is not rolled back. It is thus desirable to have
a robust way of handling these conflicts, which can later be reused for
handling NETDEV_CHANGE as well.
To fix this, when a conflicting tunnel is created, instead of failing,
simply pull the old tunnel to slow path and reject offloading the
new one.
Introduce two functions: mlxsw_sp_ipip_entry_demote_tunnel() and
mlxsw_sp_ipip_demote_tunnel_by_saddr() to handle this. Make them both
public, because they will be useful later on in this patchset.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-03 16:03:40 +07:00
|
|
|
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);
|
2017-09-25 15:32:25 +07:00
|
|
|
struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
|
|
|
|
struct mlxsw_sp_nexthop *nh);
|
|
|
|
bool mlxsw_sp_nexthop_offload(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,
|
2017-10-23 04:11:43 +07:00
|
|
|
u32 *p_adj_size, u32 *p_adj_hash_index);
|
2017-09-25 15:32:25 +07:00
|
|
|
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);
|
|
|
|
#define mlxsw_sp_nexthop_for_each(nh, router) \
|
|
|
|
for (nh = mlxsw_sp_nexthop_next(router, NULL); nh; \
|
|
|
|
nh = mlxsw_sp_nexthop_next(router, nh))
|
2017-09-25 15:32:28 +07:00
|
|
|
int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_nexthop *nh, u64 *p_counter);
|
2017-09-25 15:32:30 +07:00
|
|
|
int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
|
|
|
|
struct mlxsw_sp_nexthop *nh);
|
|
|
|
void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_nexthop *nh);
|
|
|
|
void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
struct mlxsw_sp_nexthop *nh);
|
2017-03-28 22:24:15 +07:00
|
|
|
|
2017-11-03 16:03:42 +07:00
|
|
|
static inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,
|
|
|
|
const union mlxsw_sp_l3addr *addr2)
|
|
|
|
{
|
|
|
|
return !memcmp(addr1, addr2, sizeof(*addr1));
|
|
|
|
}
|
|
|
|
|
2017-03-28 22:24:15 +07:00
|
|
|
#endif /* _MLXSW_ROUTER_H_*/
|