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