xref: /linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h (revision 2a60c460b5889d5892ac809f7a26ab89e2580bf8)
19948a064SJiri Pirko /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
29948a064SJiri Pirko /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
3e0c0afd8SArkadi Sharshevsky 
4e0c0afd8SArkadi Sharshevsky #ifndef _MLXSW_ROUTER_H_
5e0c0afd8SArkadi Sharshevsky #define _MLXSW_ROUTER_H_
6e0c0afd8SArkadi Sharshevsky 
7e0c0afd8SArkadi Sharshevsky #include "spectrum.h"
86ddb7426SPetr Machata #include "reg.h"
9e0c0afd8SArkadi Sharshevsky 
10*2a60c460SIdo Schimmel struct mlxsw_sp_router {
11*2a60c460SIdo Schimmel 	struct mlxsw_sp *mlxsw_sp;
12*2a60c460SIdo Schimmel 	struct mlxsw_sp_rif **rifs;
13*2a60c460SIdo Schimmel 	struct mlxsw_sp_vr *vrs;
14*2a60c460SIdo Schimmel 	struct rhashtable neigh_ht;
15*2a60c460SIdo Schimmel 	struct rhashtable nexthop_group_ht;
16*2a60c460SIdo Schimmel 	struct rhashtable nexthop_ht;
17*2a60c460SIdo Schimmel 	struct list_head nexthop_list;
18*2a60c460SIdo Schimmel 	struct {
19*2a60c460SIdo Schimmel 		/* One tree for each protocol: IPv4 and IPv6 */
20*2a60c460SIdo Schimmel 		struct mlxsw_sp_lpm_tree *proto_trees[2];
21*2a60c460SIdo Schimmel 		struct mlxsw_sp_lpm_tree *trees;
22*2a60c460SIdo Schimmel 		unsigned int tree_count;
23*2a60c460SIdo Schimmel 	} lpm;
24*2a60c460SIdo Schimmel 	struct {
25*2a60c460SIdo Schimmel 		struct delayed_work dw;
26*2a60c460SIdo Schimmel 		unsigned long interval;	/* ms */
27*2a60c460SIdo Schimmel 	} neighs_update;
28*2a60c460SIdo Schimmel 	struct delayed_work nexthop_probe_dw;
29*2a60c460SIdo Schimmel #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */
30*2a60c460SIdo Schimmel 	struct list_head nexthop_neighs_list;
31*2a60c460SIdo Schimmel 	struct list_head ipip_list;
32*2a60c460SIdo Schimmel 	bool aborted;
33*2a60c460SIdo Schimmel 	struct notifier_block fib_nb;
34*2a60c460SIdo Schimmel 	struct notifier_block netevent_nb;
35*2a60c460SIdo Schimmel 	struct notifier_block inetaddr_nb;
36*2a60c460SIdo Schimmel 	struct notifier_block inet6addr_nb;
37*2a60c460SIdo Schimmel 	const struct mlxsw_sp_rif_ops **rif_ops_arr;
38*2a60c460SIdo Schimmel 	const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
39*2a60c460SIdo Schimmel 	u32 adj_discard_index;
40*2a60c460SIdo Schimmel 	bool adj_discard_index_valid;
41*2a60c460SIdo Schimmel };
42*2a60c460SIdo Schimmel 
4392107cfbSPetr Machata struct mlxsw_sp_rif_ipip_lb;
446ddb7426SPetr Machata struct mlxsw_sp_rif_ipip_lb_config {
456ddb7426SPetr Machata 	enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
466ddb7426SPetr Machata 	u32 okey;
476ddb7426SPetr Machata 	enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */
486ddb7426SPetr Machata 	union mlxsw_sp_l3addr saddr;
496ddb7426SPetr Machata };
506ddb7426SPetr Machata 
51e0c0afd8SArkadi Sharshevsky enum mlxsw_sp_rif_counter_dir {
52e0c0afd8SArkadi Sharshevsky 	MLXSW_SP_RIF_COUNTER_INGRESS,
53e0c0afd8SArkadi Sharshevsky 	MLXSW_SP_RIF_COUNTER_EGRESS,
54e0c0afd8SArkadi Sharshevsky };
55e0c0afd8SArkadi Sharshevsky 
56f17cc84dSArkadi Sharshevsky struct mlxsw_sp_neigh_entry;
57c556cd28SArkadi Sharshevsky struct mlxsw_sp_nexthop;
580c5f1cd5SPetr Machata struct mlxsw_sp_ipip_entry;
59f17cc84dSArkadi Sharshevsky 
605f9efffbSIdo Schimmel struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
615f9efffbSIdo Schimmel 					   u16 rif_index);
62fd1b9d41SArkadi Sharshevsky u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
6392107cfbSPetr Machata u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif);
6492107cfbSPetr Machata u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
65311596f5SNir Dotan u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif);
664cf04f3fSPetr Machata u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev);
67fd1b9d41SArkadi Sharshevsky int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
6891e4d59aSYotam Gigi const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif);
69e0c0afd8SArkadi Sharshevsky int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
70e0c0afd8SArkadi Sharshevsky 				   struct mlxsw_sp_rif *rif,
71e0c0afd8SArkadi Sharshevsky 				   enum mlxsw_sp_rif_counter_dir dir,
72e0c0afd8SArkadi Sharshevsky 				   u64 *cnt);
73e0c0afd8SArkadi Sharshevsky void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
74e0c0afd8SArkadi Sharshevsky 			       struct mlxsw_sp_rif *rif,
75e0c0afd8SArkadi Sharshevsky 			       enum mlxsw_sp_rif_counter_dir dir);
76e0c0afd8SArkadi Sharshevsky int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
77e0c0afd8SArkadi Sharshevsky 			       struct mlxsw_sp_rif *rif,
78e0c0afd8SArkadi Sharshevsky 			       enum mlxsw_sp_rif_counter_dir dir);
79f17cc84dSArkadi Sharshevsky struct mlxsw_sp_neigh_entry *
80f17cc84dSArkadi Sharshevsky mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
81f17cc84dSArkadi Sharshevsky 			struct mlxsw_sp_neigh_entry *neigh_entry);
82f17cc84dSArkadi Sharshevsky int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry);
83f17cc84dSArkadi Sharshevsky unsigned char *
84f17cc84dSArkadi Sharshevsky mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry);
85f17cc84dSArkadi Sharshevsky u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
860250768cSArkadi Sharshevsky struct in6_addr *
870250768cSArkadi Sharshevsky mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
88f17cc84dSArkadi Sharshevsky 
89f17cc84dSArkadi Sharshevsky #define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif)				\
90f17cc84dSArkadi Sharshevsky 	for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry;	\
91f17cc84dSArkadi Sharshevsky 	     neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry))
927cfcbc75SArkadi Sharshevsky int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
937cfcbc75SArkadi Sharshevsky 			       struct mlxsw_sp_neigh_entry *neigh_entry,
947cfcbc75SArkadi Sharshevsky 			       u64 *p_counter);
95a481d713SArkadi Sharshevsky void
96a481d713SArkadi Sharshevsky mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
97a481d713SArkadi Sharshevsky 				    struct mlxsw_sp_neigh_entry *neigh_entry,
98a481d713SArkadi Sharshevsky 				    bool adding);
991d1056d8SArkadi Sharshevsky bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
1000c5f1cd5SPetr Machata int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
1010c5f1cd5SPetr Machata 					struct mlxsw_sp_ipip_entry *ipip_entry,
1020c5f1cd5SPetr Machata 					bool recreate_loopback,
1030c5f1cd5SPetr Machata 					bool keep_encap,
1040c5f1cd5SPetr Machata 					bool update_nexthops,
1050c5f1cd5SPetr Machata 					struct netlink_ext_ack *extack);
106af641713SPetr Machata void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,
107af641713SPetr Machata 				       struct mlxsw_sp_ipip_entry *ipip_entry);
108af641713SPetr Machata bool
109af641713SPetr Machata mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,
110af641713SPetr Machata 				     enum mlxsw_sp_l3proto ul_proto,
111af641713SPetr Machata 				     union mlxsw_sp_l3addr saddr,
112af641713SPetr Machata 				     u32 ul_tb_id,
113af641713SPetr Machata 				     const struct mlxsw_sp_ipip_entry *except);
114c556cd28SArkadi Sharshevsky struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
115c556cd28SArkadi Sharshevsky 					       struct mlxsw_sp_nexthop *nh);
116c556cd28SArkadi Sharshevsky bool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh);
117c556cd28SArkadi Sharshevsky unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh);
118c556cd28SArkadi Sharshevsky int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index,
119e69cd9d7SIdo Schimmel 			     u32 *p_adj_size, u32 *p_adj_hash_index);
120c556cd28SArkadi Sharshevsky struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh);
121c556cd28SArkadi Sharshevsky bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh);
122c556cd28SArkadi Sharshevsky #define mlxsw_sp_nexthop_for_each(nh, router)				\
123c556cd28SArkadi Sharshevsky 	for (nh = mlxsw_sp_nexthop_next(router, NULL); nh;		\
124c556cd28SArkadi Sharshevsky 	     nh = mlxsw_sp_nexthop_next(router, nh))
125a5390278SArkadi Sharshevsky int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
126a5390278SArkadi Sharshevsky 				 struct mlxsw_sp_nexthop *nh, u64 *p_counter);
127427e652aSArkadi Sharshevsky int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
128427e652aSArkadi Sharshevsky 			    struct mlxsw_sp_nexthop *nh);
129427e652aSArkadi Sharshevsky void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
130427e652aSArkadi Sharshevsky 				    struct mlxsw_sp_nexthop *nh);
131427e652aSArkadi Sharshevsky void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
132427e652aSArkadi Sharshevsky 				   struct mlxsw_sp_nexthop *nh);
133e0c0afd8SArkadi Sharshevsky 
1344cf04f3fSPetr Machata static inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,
1354cf04f3fSPetr Machata 				      const union mlxsw_sp_l3addr *addr2)
1364cf04f3fSPetr Machata {
1374cf04f3fSPetr Machata 	return !memcmp(addr1, addr2, sizeof(*addr1));
1384cf04f3fSPetr Machata }
1394cf04f3fSPetr Machata 
1404a44ee67SAmit Cohen int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp);
1414a44ee67SAmit Cohen int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp);
1424a44ee67SAmit Cohen 
143e0c0afd8SArkadi Sharshevsky #endif /* _MLXSW_ROUTER_H_*/
144