1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #ifndef _MLXSW_ROUTER_H_ 5 #define _MLXSW_ROUTER_H_ 6 7 #include "spectrum.h" 8 #include "reg.h" 9 10 struct mlxsw_sp_router_nve_decap { 11 u32 ul_tb_id; 12 u32 tunnel_index; 13 enum mlxsw_sp_l3proto ul_proto; 14 union mlxsw_sp_l3addr ul_sip; 15 u8 valid:1; 16 }; 17 18 /* gen_pool_alloc() returns 0 when allocation fails, so use an offset */ 19 #define MLXSW_SP_ROUTER_GENALLOC_OFFSET 0x100 20 21 struct mlxsw_sp_router { 22 struct mlxsw_sp *mlxsw_sp; 23 struct gen_pool *rifs_table; 24 struct mlxsw_sp_rif **rifs; 25 struct idr rif_mac_profiles_idr; 26 atomic_t rif_mac_profiles_count; 27 atomic_t rifs_count; 28 u8 max_rif_mac_profile; 29 struct mlxsw_sp_vr *vrs; 30 struct rhashtable neigh_ht; 31 struct rhashtable nexthop_group_ht; 32 struct rhashtable nexthop_ht; 33 struct list_head nexthop_list; 34 struct { 35 /* One tree for each protocol: IPv4 and IPv6 */ 36 struct mlxsw_sp_lpm_tree *proto_trees[2]; 37 struct mlxsw_sp_lpm_tree *trees; 38 unsigned int tree_count; 39 } lpm; 40 struct { 41 struct delayed_work dw; 42 unsigned long interval; /* ms */ 43 atomic_t neigh_count; 44 } neighs_update; 45 struct delayed_work nexthop_probe_dw; 46 #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ 47 struct list_head nexthop_neighs_list; 48 struct list_head ipip_list; 49 struct notifier_block nexthop_nb; 50 struct notifier_block fib_nb; 51 struct notifier_block netevent_nb; 52 struct notifier_block inetaddr_nb; 53 struct notifier_block inet6addr_nb; 54 struct notifier_block netdevice_nb; 55 const struct mlxsw_sp_rif_ops **rif_ops_arr; 56 const struct mlxsw_sp_ipip_ops **ipip_ops_arr; 57 struct mlxsw_sp_router_nve_decap nve_decap_config; 58 struct mutex lock; /* Protects shared router resources */ 59 struct mlxsw_sp_fib_entry_op_ctx *ll_op_ctx; 60 u16 lb_rif_index; 61 const struct mlxsw_sp_adj_grp_size_range *adj_grp_size_ranges; 62 size_t adj_grp_size_ranges_count; 63 struct delayed_work nh_grp_activity_dw; 64 struct list_head nh_res_grp_list; 65 bool inc_parsing_depth; 66 refcount_t num_groups; 67 u32 adj_trap_index; 68 }; 69 70 struct mlxsw_sp_rif_ipip_lb; 71 struct mlxsw_sp_rif_ipip_lb_config { 72 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 73 u32 okey; 74 enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */ 75 union mlxsw_sp_l3addr saddr; 76 }; 77 78 enum mlxsw_sp_rif_counter_dir { 79 MLXSW_SP_RIF_COUNTER_INGRESS, 80 MLXSW_SP_RIF_COUNTER_EGRESS, 81 }; 82 83 struct mlxsw_sp_neigh_entry; 84 struct mlxsw_sp_nexthop; 85 struct mlxsw_sp_ipip_entry; 86 87 struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, 88 u16 rif_index); 89 u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif); 90 u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif); 91 u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); 92 u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev); 93 int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); 94 const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif); 95 int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, 96 struct mlxsw_sp_rif *rif, 97 enum mlxsw_sp_rif_counter_dir dir, 98 u64 *cnt); 99 void mlxsw_sp_rif_counter_free(struct mlxsw_sp_rif *rif, 100 enum mlxsw_sp_rif_counter_dir dir); 101 int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp_rif *rif, 102 enum mlxsw_sp_rif_counter_dir dir); 103 struct mlxsw_sp_neigh_entry * 104 mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif, 105 struct mlxsw_sp_neigh_entry *neigh_entry); 106 int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry); 107 unsigned char * 108 mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry); 109 u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 110 struct in6_addr * 111 mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 112 113 #define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) \ 114 for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry; \ 115 neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry)) 116 int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp, 117 struct mlxsw_sp_neigh_entry *neigh_entry, 118 u64 *p_counter); 119 void 120 mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp, 121 struct mlxsw_sp_neigh_entry *neigh_entry, 122 bool adding); 123 bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry); 124 int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, 125 struct mlxsw_sp_ipip_entry *ipip_entry, 126 bool recreate_loopback, 127 bool keep_encap, 128 bool update_nexthops, 129 struct netlink_ext_ack *extack); 130 void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp, 131 struct mlxsw_sp_ipip_entry *ipip_entry); 132 bool 133 mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp, 134 enum mlxsw_sp_l3proto ul_proto, 135 union mlxsw_sp_l3addr saddr, 136 u32 ul_tb_id, 137 const struct mlxsw_sp_ipip_entry *except); 138 struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router, 139 struct mlxsw_sp_nexthop *nh); 140 bool mlxsw_sp_nexthop_is_forward(const struct mlxsw_sp_nexthop *nh); 141 unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh); 142 int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index, 143 u32 *p_adj_size, u32 *p_adj_hash_index); 144 struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh); 145 bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh); 146 #define mlxsw_sp_nexthop_for_each(nh, router) \ 147 for (nh = mlxsw_sp_nexthop_next(router, NULL); nh; \ 148 nh = mlxsw_sp_nexthop_next(router, nh)) 149 int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp, 150 struct mlxsw_sp_nexthop *nh, u64 *p_counter); 151 int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 152 struct mlxsw_sp_nexthop *nh, bool force, 153 char *ratr_pl); 154 void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp, 155 struct mlxsw_sp_nexthop *nh); 156 void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp, 157 struct mlxsw_sp_nexthop *nh); 158 159 static inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1, 160 const union mlxsw_sp_l3addr *addr2) 161 { 162 return !memcmp(addr1, addr2, sizeof(*addr1)); 163 } 164 165 int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp); 166 int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp); 167 struct net_device * 168 mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev); 169 170 #endif /* _MLXSW_ROUTER_H_*/ 171