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 108e18d85eSIdo Schimmel struct mlxsw_sp_router_nve_decap { 118e18d85eSIdo Schimmel u32 ul_tb_id; 128e18d85eSIdo Schimmel u32 tunnel_index; 138e18d85eSIdo Schimmel enum mlxsw_sp_l3proto ul_proto; 148e18d85eSIdo Schimmel union mlxsw_sp_l3addr ul_sip; 158e18d85eSIdo Schimmel u8 valid:1; 168e18d85eSIdo Schimmel }; 178e18d85eSIdo Schimmel 18*40ef76deSIdo Schimmel /* gen_pool_alloc() returns 0 when allocation fails, so use an offset */ 19*40ef76deSIdo Schimmel #define MLXSW_SP_ROUTER_GENALLOC_OFFSET 0x100 20*40ef76deSIdo Schimmel 212a60c460SIdo Schimmel struct mlxsw_sp_router { 222a60c460SIdo Schimmel struct mlxsw_sp *mlxsw_sp; 23*40ef76deSIdo Schimmel struct gen_pool *rifs_table; 242a60c460SIdo Schimmel struct mlxsw_sp_rif **rifs; 25605d25cdSDanielle Ratson struct idr rif_mac_profiles_idr; 26605d25cdSDanielle Ratson atomic_t rif_mac_profiles_count; 27b9840fe0SPetr Machata atomic_t rifs_count; 28605d25cdSDanielle Ratson u8 max_rif_mac_profile; 292a60c460SIdo Schimmel struct mlxsw_sp_vr *vrs; 302a60c460SIdo Schimmel struct rhashtable neigh_ht; 312a60c460SIdo Schimmel struct rhashtable nexthop_group_ht; 322a60c460SIdo Schimmel struct rhashtable nexthop_ht; 332a60c460SIdo Schimmel struct list_head nexthop_list; 342a60c460SIdo Schimmel struct { 352a60c460SIdo Schimmel /* One tree for each protocol: IPv4 and IPv6 */ 362a60c460SIdo Schimmel struct mlxsw_sp_lpm_tree *proto_trees[2]; 372a60c460SIdo Schimmel struct mlxsw_sp_lpm_tree *trees; 382a60c460SIdo Schimmel unsigned int tree_count; 392a60c460SIdo Schimmel } lpm; 402a60c460SIdo Schimmel struct { 412a60c460SIdo Schimmel struct delayed_work dw; 422a60c460SIdo Schimmel unsigned long interval; /* ms */ 43cff94376SIdo Schimmel atomic_t neigh_count; 442a60c460SIdo Schimmel } neighs_update; 452a60c460SIdo Schimmel struct delayed_work nexthop_probe_dw; 462a60c460SIdo Schimmel #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ 472a60c460SIdo Schimmel struct list_head nexthop_neighs_list; 482a60c460SIdo Schimmel struct list_head ipip_list; 492a014b20SIdo Schimmel struct notifier_block nexthop_nb; 502a60c460SIdo Schimmel struct notifier_block fib_nb; 512a60c460SIdo Schimmel struct notifier_block netevent_nb; 522a60c460SIdo Schimmel struct notifier_block inetaddr_nb; 532a60c460SIdo Schimmel struct notifier_block inet6addr_nb; 540a27cb16SPetr Machata struct notifier_block netdevice_nb; 552a60c460SIdo Schimmel const struct mlxsw_sp_rif_ops **rif_ops_arr; 562a60c460SIdo Schimmel const struct mlxsw_sp_ipip_ops **ipip_ops_arr; 578e18d85eSIdo Schimmel struct mlxsw_sp_router_nve_decap nve_decap_config; 5820bf5d82SIdo Schimmel struct mutex lock; /* Protects shared router resources */ 5991d20d71SJiri Pirko struct mlxsw_sp_fib_entry_op_ctx *ll_op_ctx; 6007c78536SIdo Schimmel u16 lb_rif_index; 61ea037b23SIdo Schimmel const struct mlxsw_sp_adj_grp_size_range *adj_grp_size_ranges; 62ea037b23SIdo Schimmel size_t adj_grp_size_ranges_count; 63debd2b3bSIdo Schimmel struct delayed_work nh_grp_activity_dw; 64debd2b3bSIdo Schimmel struct list_head nh_res_grp_list; 6543c1b833SAmit Cohen bool inc_parsing_depth; 664bdf80bcSIdo Schimmel refcount_t num_groups; 674bdf80bcSIdo Schimmel u32 adj_trap_index; 68803be108SJiri Pirko }; 69803be108SJiri Pirko 7092107cfbSPetr Machata struct mlxsw_sp_rif_ipip_lb; 716ddb7426SPetr Machata struct mlxsw_sp_rif_ipip_lb_config { 726ddb7426SPetr Machata enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 736ddb7426SPetr Machata u32 okey; 746ddb7426SPetr Machata enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */ 756ddb7426SPetr Machata union mlxsw_sp_l3addr saddr; 766ddb7426SPetr Machata }; 776ddb7426SPetr Machata 78e0c0afd8SArkadi Sharshevsky enum mlxsw_sp_rif_counter_dir { 79e0c0afd8SArkadi Sharshevsky MLXSW_SP_RIF_COUNTER_INGRESS, 80e0c0afd8SArkadi Sharshevsky MLXSW_SP_RIF_COUNTER_EGRESS, 81e0c0afd8SArkadi Sharshevsky }; 82e0c0afd8SArkadi Sharshevsky 83f17cc84dSArkadi Sharshevsky struct mlxsw_sp_neigh_entry; 84c556cd28SArkadi Sharshevsky struct mlxsw_sp_nexthop; 850c5f1cd5SPetr Machata struct mlxsw_sp_ipip_entry; 86f17cc84dSArkadi Sharshevsky 875f9efffbSIdo Schimmel struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, 885f9efffbSIdo Schimmel u16 rif_index); 8992107cfbSPetr Machata u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif); 9092107cfbSPetr Machata u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif); 91311596f5SNir Dotan u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); 924cf04f3fSPetr Machata u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev); 93fd1b9d41SArkadi Sharshevsky int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); 9491e4d59aSYotam Gigi const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif); 95e0c0afd8SArkadi Sharshevsky int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, 96e0c0afd8SArkadi Sharshevsky struct mlxsw_sp_rif *rif, 97e0c0afd8SArkadi Sharshevsky enum mlxsw_sp_rif_counter_dir dir, 98e0c0afd8SArkadi Sharshevsky u64 *cnt); 999834e246SPetr Machata void mlxsw_sp_rif_counter_free(struct mlxsw_sp_rif *rif, 100e0c0afd8SArkadi Sharshevsky enum mlxsw_sp_rif_counter_dir dir); 1019834e246SPetr Machata int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp_rif *rif, 102e0c0afd8SArkadi Sharshevsky enum mlxsw_sp_rif_counter_dir dir); 103f17cc84dSArkadi Sharshevsky struct mlxsw_sp_neigh_entry * 104f17cc84dSArkadi Sharshevsky mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif, 105f17cc84dSArkadi Sharshevsky struct mlxsw_sp_neigh_entry *neigh_entry); 106f17cc84dSArkadi Sharshevsky int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry); 107f17cc84dSArkadi Sharshevsky unsigned char * 108f17cc84dSArkadi Sharshevsky mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry); 109f17cc84dSArkadi Sharshevsky u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 1100250768cSArkadi Sharshevsky struct in6_addr * 1110250768cSArkadi Sharshevsky mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 112f17cc84dSArkadi Sharshevsky 113f17cc84dSArkadi Sharshevsky #define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) \ 114f17cc84dSArkadi Sharshevsky for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry; \ 115f17cc84dSArkadi Sharshevsky neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry)) 1167cfcbc75SArkadi Sharshevsky int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp, 1177cfcbc75SArkadi Sharshevsky struct mlxsw_sp_neigh_entry *neigh_entry, 1187cfcbc75SArkadi Sharshevsky u64 *p_counter); 119a481d713SArkadi Sharshevsky void 120a481d713SArkadi Sharshevsky mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp, 121a481d713SArkadi Sharshevsky struct mlxsw_sp_neigh_entry *neigh_entry, 122a481d713SArkadi Sharshevsky bool adding); 1231d1056d8SArkadi Sharshevsky bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry); 1240c5f1cd5SPetr Machata int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, 1250c5f1cd5SPetr Machata struct mlxsw_sp_ipip_entry *ipip_entry, 1260c5f1cd5SPetr Machata bool recreate_loopback, 1270c5f1cd5SPetr Machata bool keep_encap, 1280c5f1cd5SPetr Machata bool update_nexthops, 1290c5f1cd5SPetr Machata struct netlink_ext_ack *extack); 130af641713SPetr Machata void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp, 131af641713SPetr Machata struct mlxsw_sp_ipip_entry *ipip_entry); 132af641713SPetr Machata bool 133af641713SPetr Machata mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp, 134af641713SPetr Machata enum mlxsw_sp_l3proto ul_proto, 135af641713SPetr Machata union mlxsw_sp_l3addr saddr, 136af641713SPetr Machata u32 ul_tb_id, 137af641713SPetr Machata const struct mlxsw_sp_ipip_entry *except); 138c556cd28SArkadi Sharshevsky struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router, 139c556cd28SArkadi Sharshevsky struct mlxsw_sp_nexthop *nh); 14026df5accSIdo Schimmel bool mlxsw_sp_nexthop_is_forward(const struct mlxsw_sp_nexthop *nh); 141c556cd28SArkadi Sharshevsky unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh); 142c556cd28SArkadi Sharshevsky int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index, 143e69cd9d7SIdo Schimmel u32 *p_adj_size, u32 *p_adj_hash_index); 144c556cd28SArkadi Sharshevsky struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh); 145c556cd28SArkadi Sharshevsky bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh); 146c556cd28SArkadi Sharshevsky #define mlxsw_sp_nexthop_for_each(nh, router) \ 147c556cd28SArkadi Sharshevsky for (nh = mlxsw_sp_nexthop_next(router, NULL); nh; \ 148c556cd28SArkadi Sharshevsky nh = mlxsw_sp_nexthop_next(router, nh)) 149a5390278SArkadi Sharshevsky int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp, 150a5390278SArkadi Sharshevsky struct mlxsw_sp_nexthop *nh, u64 *p_counter); 151424603ccSIdo Schimmel int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 152197fdfd1SIdo Schimmel struct mlxsw_sp_nexthop *nh, bool force, 153197fdfd1SIdo Schimmel char *ratr_pl); 154427e652aSArkadi Sharshevsky void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp, 155427e652aSArkadi Sharshevsky struct mlxsw_sp_nexthop *nh); 156427e652aSArkadi Sharshevsky void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp, 157427e652aSArkadi Sharshevsky struct mlxsw_sp_nexthop *nh); 158e0c0afd8SArkadi Sharshevsky 1594cf04f3fSPetr Machata static inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1, 1604cf04f3fSPetr Machata const union mlxsw_sp_l3addr *addr2) 1614cf04f3fSPetr Machata { 1624cf04f3fSPetr Machata return !memcmp(addr1, addr2, sizeof(*addr1)); 1634cf04f3fSPetr Machata } 1644cf04f3fSPetr Machata 1654a44ee67SAmit Cohen int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp); 1664a44ee67SAmit Cohen int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp); 16759bf980dSAmit Cohen struct net_device * 16859bf980dSAmit Cohen mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev); 1694a44ee67SAmit Cohen 170e0c0afd8SArkadi Sharshevsky #endif /* _MLXSW_ROUTER_H_*/ 171