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 struct notifier_block inetaddr_valid_nb; 56 struct notifier_block inet6addr_valid_nb; 57 const struct mlxsw_sp_rif_ops **rif_ops_arr; 58 const struct mlxsw_sp_ipip_ops **ipip_ops_arr; 59 struct mlxsw_sp_router_nve_decap nve_decap_config; 60 struct mutex lock; /* Protects shared router resources */ 61 struct mlxsw_sp_fib_entry_op_ctx *ll_op_ctx; 62 u16 lb_rif_index; 63 const struct mlxsw_sp_adj_grp_size_range *adj_grp_size_ranges; 64 size_t adj_grp_size_ranges_count; 65 struct delayed_work nh_grp_activity_dw; 66 struct list_head nh_res_grp_list; 67 bool inc_parsing_depth; 68 refcount_t num_groups; 69 u32 adj_trap_index; 70 }; 71 72 struct mlxsw_sp_rif_ipip_lb; 73 struct mlxsw_sp_rif_ipip_lb_config { 74 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 75 u32 okey; 76 enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */ 77 union mlxsw_sp_l3addr saddr; 78 }; 79 80 enum mlxsw_sp_rif_counter_dir { 81 MLXSW_SP_RIF_COUNTER_INGRESS, 82 MLXSW_SP_RIF_COUNTER_EGRESS, 83 }; 84 85 struct mlxsw_sp_neigh_entry; 86 struct mlxsw_sp_nexthop; 87 struct mlxsw_sp_ipip_entry; 88 89 struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, 90 u16 rif_index); 91 u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif); 92 u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif); 93 u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); 94 u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev); 95 int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); 96 bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif); 97 bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif, 98 const struct net_device *dev); 99 int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, 100 struct mlxsw_sp_rif *rif, 101 enum mlxsw_sp_rif_counter_dir dir, 102 u64 *cnt); 103 void mlxsw_sp_rif_counter_free(struct mlxsw_sp_rif *rif, 104 enum mlxsw_sp_rif_counter_dir dir); 105 int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp_rif *rif, 106 enum mlxsw_sp_rif_counter_dir dir); 107 struct mlxsw_sp_neigh_entry * 108 mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif, 109 struct mlxsw_sp_neigh_entry *neigh_entry); 110 int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry); 111 unsigned char * 112 mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry); 113 u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 114 struct in6_addr * 115 mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry); 116 117 #define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) \ 118 for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry; \ 119 neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry)) 120 int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp, 121 struct mlxsw_sp_neigh_entry *neigh_entry, 122 u64 *p_counter); 123 void 124 mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp, 125 struct mlxsw_sp_neigh_entry *neigh_entry, 126 bool adding); 127 bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry); 128 int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, 129 struct mlxsw_sp_ipip_entry *ipip_entry, 130 bool recreate_loopback, 131 bool keep_encap, 132 bool update_nexthops, 133 struct netlink_ext_ack *extack); 134 void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp, 135 struct mlxsw_sp_ipip_entry *ipip_entry); 136 bool 137 mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp, 138 enum mlxsw_sp_l3proto ul_proto, 139 union mlxsw_sp_l3addr saddr, 140 u32 ul_tb_id, 141 const struct mlxsw_sp_ipip_entry *except); 142 struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router, 143 struct mlxsw_sp_nexthop *nh); 144 bool mlxsw_sp_nexthop_is_forward(const struct mlxsw_sp_nexthop *nh); 145 unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh); 146 int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index, 147 u32 *p_adj_size, u32 *p_adj_hash_index); 148 struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh); 149 bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh); 150 #define mlxsw_sp_nexthop_for_each(nh, router) \ 151 for (nh = mlxsw_sp_nexthop_next(router, NULL); nh; \ 152 nh = mlxsw_sp_nexthop_next(router, nh)) 153 int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp, 154 struct mlxsw_sp_nexthop *nh, u64 *p_counter); 155 int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 156 struct mlxsw_sp_nexthop *nh, bool force, 157 char *ratr_pl); 158 void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp, 159 struct mlxsw_sp_nexthop *nh); 160 void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp, 161 struct mlxsw_sp_nexthop *nh); 162 163 static inline bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1, 164 const union mlxsw_sp_l3addr *addr2) 165 { 166 return !memcmp(addr1, addr2, sizeof(*addr1)); 167 } 168 169 int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp); 170 int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp); 171 struct net_device * 172 mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev); 173 int mlxsw_sp_router_port_join_lag(struct mlxsw_sp_port *mlxsw_sp_port, 174 struct net_device *lag_dev, 175 struct netlink_ext_ack *extack); 176 177 #endif /* _MLXSW_ROUTER_H_*/ 178