18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
28c2ecf20Sopenharmony_ci/* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#ifndef _MLXSW_ROUTER_H_
58c2ecf20Sopenharmony_ci#define _MLXSW_ROUTER_H_
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include "spectrum.h"
88c2ecf20Sopenharmony_ci#include "reg.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistruct mlxsw_sp_router_nve_decap {
118c2ecf20Sopenharmony_ci	u32 ul_tb_id;
128c2ecf20Sopenharmony_ci	u32 tunnel_index;
138c2ecf20Sopenharmony_ci	enum mlxsw_sp_l3proto ul_proto;
148c2ecf20Sopenharmony_ci	union mlxsw_sp_l3addr ul_sip;
158c2ecf20Sopenharmony_ci	u8 valid:1;
168c2ecf20Sopenharmony_ci};
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct mlxsw_sp_router {
198c2ecf20Sopenharmony_ci	struct mlxsw_sp *mlxsw_sp;
208c2ecf20Sopenharmony_ci	struct mlxsw_sp_rif **rifs;
218c2ecf20Sopenharmony_ci	struct mlxsw_sp_vr *vrs;
228c2ecf20Sopenharmony_ci	struct rhashtable neigh_ht;
238c2ecf20Sopenharmony_ci	struct rhashtable nexthop_group_ht;
248c2ecf20Sopenharmony_ci	struct rhashtable nexthop_ht;
258c2ecf20Sopenharmony_ci	struct list_head nexthop_list;
268c2ecf20Sopenharmony_ci	struct {
278c2ecf20Sopenharmony_ci		/* One tree for each protocol: IPv4 and IPv6 */
288c2ecf20Sopenharmony_ci		struct mlxsw_sp_lpm_tree *proto_trees[2];
298c2ecf20Sopenharmony_ci		struct mlxsw_sp_lpm_tree *trees;
308c2ecf20Sopenharmony_ci		unsigned int tree_count;
318c2ecf20Sopenharmony_ci	} lpm;
328c2ecf20Sopenharmony_ci	struct {
338c2ecf20Sopenharmony_ci		struct delayed_work dw;
348c2ecf20Sopenharmony_ci		unsigned long interval;	/* ms */
358c2ecf20Sopenharmony_ci	} neighs_update;
368c2ecf20Sopenharmony_ci	struct delayed_work nexthop_probe_dw;
378c2ecf20Sopenharmony_ci#define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */
388c2ecf20Sopenharmony_ci	struct list_head nexthop_neighs_list;
398c2ecf20Sopenharmony_ci	struct list_head ipip_list;
408c2ecf20Sopenharmony_ci	bool aborted;
418c2ecf20Sopenharmony_ci	struct notifier_block fib_nb;
428c2ecf20Sopenharmony_ci	struct notifier_block netevent_nb;
438c2ecf20Sopenharmony_ci	struct notifier_block inetaddr_nb;
448c2ecf20Sopenharmony_ci	struct notifier_block inet6addr_nb;
458c2ecf20Sopenharmony_ci	const struct mlxsw_sp_rif_ops **rif_ops_arr;
468c2ecf20Sopenharmony_ci	const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
478c2ecf20Sopenharmony_ci	u32 adj_discard_index;
488c2ecf20Sopenharmony_ci	bool adj_discard_index_valid;
498c2ecf20Sopenharmony_ci	struct mlxsw_sp_router_nve_decap nve_decap_config;
508c2ecf20Sopenharmony_ci	struct mutex lock; /* Protects shared router resources */
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistruct mlxsw_sp_rif_ipip_lb;
548c2ecf20Sopenharmony_cistruct mlxsw_sp_rif_ipip_lb_config {
558c2ecf20Sopenharmony_ci	enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
568c2ecf20Sopenharmony_ci	u32 okey;
578c2ecf20Sopenharmony_ci	enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */
588c2ecf20Sopenharmony_ci	union mlxsw_sp_l3addr saddr;
598c2ecf20Sopenharmony_ci};
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cienum mlxsw_sp_rif_counter_dir {
628c2ecf20Sopenharmony_ci	MLXSW_SP_RIF_COUNTER_INGRESS,
638c2ecf20Sopenharmony_ci	MLXSW_SP_RIF_COUNTER_EGRESS,
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistruct mlxsw_sp_neigh_entry;
678c2ecf20Sopenharmony_cistruct mlxsw_sp_nexthop;
688c2ecf20Sopenharmony_cistruct mlxsw_sp_ipip_entry;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistruct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
718c2ecf20Sopenharmony_ci					   u16 rif_index);
728c2ecf20Sopenharmony_ciu16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
738c2ecf20Sopenharmony_ciu16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif);
748c2ecf20Sopenharmony_ciu16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
758c2ecf20Sopenharmony_ciu16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif);
768c2ecf20Sopenharmony_ciu32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev);
778c2ecf20Sopenharmony_ciint mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
788c2ecf20Sopenharmony_ciconst struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif);
798c2ecf20Sopenharmony_ciint mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
808c2ecf20Sopenharmony_ci				   struct mlxsw_sp_rif *rif,
818c2ecf20Sopenharmony_ci				   enum mlxsw_sp_rif_counter_dir dir,
828c2ecf20Sopenharmony_ci				   u64 *cnt);
838c2ecf20Sopenharmony_civoid mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
848c2ecf20Sopenharmony_ci			       struct mlxsw_sp_rif *rif,
858c2ecf20Sopenharmony_ci			       enum mlxsw_sp_rif_counter_dir dir);
868c2ecf20Sopenharmony_ciint mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
878c2ecf20Sopenharmony_ci			       struct mlxsw_sp_rif *rif,
888c2ecf20Sopenharmony_ci			       enum mlxsw_sp_rif_counter_dir dir);
898c2ecf20Sopenharmony_cistruct mlxsw_sp_neigh_entry *
908c2ecf20Sopenharmony_cimlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
918c2ecf20Sopenharmony_ci			struct mlxsw_sp_neigh_entry *neigh_entry);
928c2ecf20Sopenharmony_ciint mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry);
938c2ecf20Sopenharmony_ciunsigned char *
948c2ecf20Sopenharmony_cimlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry);
958c2ecf20Sopenharmony_ciu32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
968c2ecf20Sopenharmony_cistruct in6_addr *
978c2ecf20Sopenharmony_cimlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif)				\
1008c2ecf20Sopenharmony_ci	for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry;	\
1018c2ecf20Sopenharmony_ci	     neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry))
1028c2ecf20Sopenharmony_ciint mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
1038c2ecf20Sopenharmony_ci			       struct mlxsw_sp_neigh_entry *neigh_entry,
1048c2ecf20Sopenharmony_ci			       u64 *p_counter);
1058c2ecf20Sopenharmony_civoid
1068c2ecf20Sopenharmony_cimlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
1078c2ecf20Sopenharmony_ci				    struct mlxsw_sp_neigh_entry *neigh_entry,
1088c2ecf20Sopenharmony_ci				    bool adding);
1098c2ecf20Sopenharmony_cibool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
1108c2ecf20Sopenharmony_ciint __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
1118c2ecf20Sopenharmony_ci					struct mlxsw_sp_ipip_entry *ipip_entry,
1128c2ecf20Sopenharmony_ci					bool recreate_loopback,
1138c2ecf20Sopenharmony_ci					bool keep_encap,
1148c2ecf20Sopenharmony_ci					bool update_nexthops,
1158c2ecf20Sopenharmony_ci					struct netlink_ext_ack *extack);
1168c2ecf20Sopenharmony_civoid mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,
1178c2ecf20Sopenharmony_ci				       struct mlxsw_sp_ipip_entry *ipip_entry);
1188c2ecf20Sopenharmony_cibool
1198c2ecf20Sopenharmony_cimlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,
1208c2ecf20Sopenharmony_ci				     enum mlxsw_sp_l3proto ul_proto,
1218c2ecf20Sopenharmony_ci				     union mlxsw_sp_l3addr saddr,
1228c2ecf20Sopenharmony_ci				     u32 ul_tb_id,
1238c2ecf20Sopenharmony_ci				     const struct mlxsw_sp_ipip_entry *except);
1248c2ecf20Sopenharmony_cistruct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
1258c2ecf20Sopenharmony_ci					       struct mlxsw_sp_nexthop *nh);
1268c2ecf20Sopenharmony_cibool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh);
1278c2ecf20Sopenharmony_ciunsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh);
1288c2ecf20Sopenharmony_ciint mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index,
1298c2ecf20Sopenharmony_ci			     u32 *p_adj_size, u32 *p_adj_hash_index);
1308c2ecf20Sopenharmony_cistruct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh);
1318c2ecf20Sopenharmony_cibool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh);
1328c2ecf20Sopenharmony_ci#define mlxsw_sp_nexthop_for_each(nh, router)				\
1338c2ecf20Sopenharmony_ci	for (nh = mlxsw_sp_nexthop_next(router, NULL); nh;		\
1348c2ecf20Sopenharmony_ci	     nh = mlxsw_sp_nexthop_next(router, nh))
1358c2ecf20Sopenharmony_ciint mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
1368c2ecf20Sopenharmony_ci				 struct mlxsw_sp_nexthop *nh, u64 *p_counter);
1378c2ecf20Sopenharmony_ciint mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
1388c2ecf20Sopenharmony_ci			    struct mlxsw_sp_nexthop *nh);
1398c2ecf20Sopenharmony_civoid mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
1408c2ecf20Sopenharmony_ci				    struct mlxsw_sp_nexthop *nh);
1418c2ecf20Sopenharmony_civoid mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
1428c2ecf20Sopenharmony_ci				   struct mlxsw_sp_nexthop *nh);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistatic inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,
1458c2ecf20Sopenharmony_ci				      const union mlxsw_sp_l3addr *addr2)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	return !memcmp(addr1, addr2, sizeof(*addr1));
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ciint mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp);
1518c2ecf20Sopenharmony_ciint mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci#endif /* _MLXSW_ROUTER_H_*/
154