nat.h (9580B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2020 Broadcom Inc. All rights reserved. 6 * 7 * NAT - Broadcom StrataSwitch NAT API internal definitions 8 */ 9 10 #ifndef _BCM_INT_NAT_H 11 #define _BCM_INT_NAT_H 12 13 #ifdef INCLUDE_L3 14 15 #include <sal/core/sync.h> 16 17 /* NAT egress state per unit 18 - hash table of nat entry to index 19 - ref counts per entry index 20 - bitmap for allocation 21 */ 22 23 typedef struct _bcm_l3_nat_egress_hash_entry_s { 24 uint32 ip_addr; 25 uint16 vrf; 26 uint16 l4_port; 27 struct _bcm_l3_nat_egress_hash_entry_t *next; 28 uint16 nat_id; 29 } _bcm_l3_nat_egress_hash_entry_t; 30 31 typedef struct _bcm_l3_nat_egress_state_s { 32 _bcm_l3_nat_egress_hash_entry_t *_bcm_l3_nat_egress_hash_tbl[256]; 33 uint16 nat_id_refcount[2048]; 34 SHR_BITDCL *nat_id_bitmap; 35 } _bcm_l3_nat_egress_state_t; 36 37 typedef struct _bcm_l3_nat_ingress_state_s { 38 uint32 tbl_cnts[3]; 39 int snat_napt_free_idx; 40 int snat_nat_free_idx; 41 #ifdef BCM_MONTEREY_SUPPORT 42 int dnat_address_type_free_idx; 43 #endif 44 } _bcm_l3_nat_ingress_state_t; 45 46 typedef struct _bcm_l3_nat_state_s { 47 _bcm_l3_nat_egress_state_t e_state; 48 _bcm_l3_nat_ingress_state_t i_state; 49 sal_mutex_t lock; 50 } _bcm_l3_nat_state_t; 51 52 extern _bcm_l3_nat_state_t *_bcm_l3_nat_state[BCM_MAX_NUM_UNITS]; 53 54 55 /* helper struct for nat ingress age/delete */ 56 typedef struct _bcm_l3_nat_ingress_cb_context_s { 57 void *user_data; 58 bcm_l3_nat_ingress_traverse_cb user_cb; 59 soc_mem_t mem; 60 } bcm_l3_nat_ingress_cb_context_t; 61 62 /* index into table counters */ 63 #define BCM_L3_NAT_INGRESS_POOL_CNT 0 64 #define BCM_L3_NAT_INGRESS_DNAT_CNT 1 65 #define BCM_L3_NAT_INGRESS_SNAT_CNT 2 66 67 #define BCM_L3_NAT_EGRESS_INFO(_unit_) _bcm_l3_nat_state[(_unit_)]->e_state 68 #define BCM_L3_NAT_INGRESS_INFO(_unit_) _bcm_l3_nat_state[(_unit_)]->i_state 69 70 /* nat packet translate table bitmap operations */ 71 #define BCM_L3_NAT_EGRESS_ENTRIES_PER_INDEX 2 72 73 #define BCM_L3_NAT_EGRESS_HW_IDX_GET(nat_idx, hw_idx, hw_half) \ 74 do {\ 75 (hw_idx) = (nat_idx) >> 1;\ 76 (hw_half) = (nat_idx) & 1;\ 77 } while (0) 78 79 #define BCM_L3_NAT_EGRESS_SW_IDX_GET(hw_idx, hw_half) \ 80 ((hw_idx) << 1 | (hw_half)) 81 82 #define BCM_L3_NAT_FILL_SW_ENTRY_X(hw_buf, nat_info, num)\ 83 do {\ 84 int bit_count;\ 85 if (soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, (hw_buf), \ 86 MODIFY_SRC_OR_DST_##num)) { /* DIP */\ 87 /* fill DNAT/NAPT */\ 88 (nat_info)->flags |= BCM_L3_NAT_EGRESS_DNAT;\ 89 (nat_info)->dip_addr = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, \ 90 (hw_buf), IP_ADDRESS_##num);\ 91 if (soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, (hw_buf), \ 92 MODIFY_L4_PORT_OR_PREFIX_##num)) {\ 93 /* modify prefix */\ 94 bit_count = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, (hw_buf), \ 95 L4_PORT_OR_PREFIX_##num);\ 96 if (bit_count < 32) {\ 97 (nat_info)->dip_addr_mask = ((1 << bit_count) - 1) << \ 98 (32 - bit_count);\ 99 } else {\ 100 (nat_info)->dip_addr_mask = 0xffffffff;\ 101 }\ 102 } else {\ 103 /* modify port */\ 104 (nat_info)->flags |= BCM_L3_NAT_EGRESS_NAPT;\ 105 (nat_info)->dst_port = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, \ 106 (hw_buf), L4_PORT_OR_PREFIX_##num);\ 107 }\ 108 } else {\ 109 /* fill SNAT/NAPT */\ 110 (nat_info)->flags |= BCM_L3_NAT_EGRESS_SNAT;\ 111 (nat_info)->sip_addr = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, \ 112 (hw_buf), IP_ADDRESS_##num);\ 113 if (soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, (hw_buf), \ 114 MODIFY_L4_PORT_OR_PREFIX_##num)) {\ 115 /* modify prefix */\ 116 bit_count = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, (hw_buf), \ 117 L4_PORT_OR_PREFIX_##num);\ 118 if (bit_count < 32) {\ 119 (nat_info)->sip_addr_mask = ((1 << bit_count) - 1) << \ 120 (32 - bit_count);\ 121 } else {\ 122 (nat_info)->sip_addr_mask = 0xffffffff;\ 123 }\ 124 } else {\ 125 /* modify port */\ 126 (nat_info)->flags |= BCM_L3_NAT_EGRESS_NAPT;\ 127 (nat_info)->src_port = soc_EGR_NAT_PACKET_EDIT_INFOm_field32_get(unit, \ 128 (hw_buf), L4_PORT_OR_PREFIX_##num);\ 129 }\ 130 }\ 131 } while (0) 132 133 #define BCM_L3_NAT_EGRESS_INC_REF_COUNT(unit, nat_id, count) \ 134 do {\ 135 BCM_L3_NAT_EGRESS_INFO((unit)).nat_id_refcount[(nat_id)]++;\ 136 /* currently max of only 2 can be incremented per call */\ 137 if ((count) > 1) {\ 138 BCM_L3_NAT_EGRESS_INFO((unit)).nat_id_refcount[(nat_id) + 1]++;\ 139 }\ 140 } while (0) 141 142 #define BCM_L3_NAT_EGRESS_DEC_REF_COUNT(unit, nat_id) \ 143 BCM_L3_NAT_EGRESS_INFO((unit)).nat_id_refcount[(nat_id)]-- 144 145 #define BCM_L3_NAT_EGRESS_GET_REF_COUNT(unit, nat_id) \ 146 BCM_L3_NAT_EGRESS_INFO((unit)).nat_id_refcount[(nat_id)] 147 148 149 #define BCM_L3_NAT_INGRESS_GET_MEM_POINTER(unit, nat_info, mem, pool, dnat, \ 150 snat, result, mem_counter) \ 151 do {\ 152 /* figure out which mem to operate on */\ 153 if ((nat_info)->flags & BCM_L3_NAT_INGRESS_DNAT) {\ 154 if ((nat_info)->flags & BCM_L3_NAT_INGRESS_DNAT_POOL) {\ 155 (mem) = ING_DNAT_ADDRESS_TYPEm;\ 156 (result) = &(pool);\ 157 (mem_counter) = BCM_L3_NAT_INGRESS_POOL_CNT;\ 158 }\ 159 else {\ 160 if (SOC_MEM_IS_VALID(unit, L3_ENTRY_DOUBLEm)) {\ 161 (mem) = L3_ENTRY_DOUBLEm;\ 162 } else {\ 163 (mem) = L3_ENTRY_IPV4_MULTICASTm;\ 164 }\ 165 (result) = &(dnat);\ 166 (mem_counter) = BCM_L3_NAT_INGRESS_DNAT_CNT;\ 167 }\ 168 } else {\ 169 (mem) = ING_SNATm;\ 170 (result) = &(snat);\ 171 (mem_counter) = BCM_L3_NAT_INGRESS_SNAT_CNT;\ 172 }\ 173 } while (0) 174 175 /* no counters */ 176 #define BCM_L3_NAT_INGRESS_GET_MEM_ONLY(unit, nat_info, mem, pool, dnat, \ 177 snat, result) \ 178 do {\ 179 /* figure out which mem to operate on */\ 180 if ((nat_info)->flags & BCM_L3_NAT_INGRESS_DNAT) {\ 181 if ((nat_info)->flags & BCM_L3_NAT_INGRESS_DNAT_POOL) {\ 182 (mem) = ING_DNAT_ADDRESS_TYPEm;\ 183 (result) = &(pool);\ 184 }\ 185 else {\ 186 (mem) = L3_ENTRY_IPV4_MULTICASTm;\ 187 if (SOC_MEM_IS_VALID(unit, L3_ENTRY_DOUBLEm)) {\ 188 (mem) = L3_ENTRY_DOUBLEm;\ 189 }\ 190 (result) = &(dnat);\ 191 }\ 192 } else {\ 193 (mem) = ING_SNATm;\ 194 (result) = &(snat);\ 195 }\ 196 } while (0) 197 198 #define BCM_L3_NAT_INGRESS_INC_TBL_CNT(unit, tbl) \ 199 BCM_L3_NAT_INGRESS_INFO((unit)).tbl_cnts[(tbl)]++; 200 201 #define BCM_L3_NAT_INGRESS_DEC_TBL_CNT(unit, tbl) \ 202 BCM_L3_NAT_INGRESS_INFO((unit)).tbl_cnts[(tbl)]--; 203 204 #define BCM_L3_NAT_INGRESS_GET_TBL_CNT(unit, tbl) \ 205 BCM_L3_NAT_INGRESS_INFO((unit)).tbl_cnts[(tbl)]; 206 207 #define BCM_L3_NAT_INGRESS_CLR_TBL_CNT(unit, tbl) \ 208 BCM_L3_NAT_INGRESS_INFO((unit)).tbl_cnts[(tbl)] = 0; 209 210 #define BCM_L3_NAT_INGRESS_SNAT_NAPT_FREE_IDX(unit) \ 211 BCM_L3_NAT_INGRESS_INFO((unit)).snat_napt_free_idx 212 213 #define BCM_L3_NAT_INGRESS_SNAT_NAT_FREE_IDX(unit) \ 214 BCM_L3_NAT_INGRESS_INFO((unit)).snat_nat_free_idx 215 216 #ifdef BCM_MONTEREY_SUPPORT 217 #define BCM_L3_NAT_ING_DNAT_ADDRESS_TYPE_FREE_IDX(unit) \ 218 BCM_L3_NAT_INGRESS_INFO((unit)).dnat_address_type_free_idx 219 #endif 220 221 #define BCM_L3_NAT_EGRESS_FLAGS_FULL_NAT(flags) \ 222 ((flags) & (BCM_L3_NAT_EGRESS_SNAT | BCM_L3_NAT_EGRESS_DNAT)) == \ 223 (BCM_L3_NAT_EGRESS_SNAT | BCM_L3_NAT_EGRESS_DNAT) 224 225 #define BCM_TD2_NAT_INGRESS_BANK_ENTRY_HASH(mem, unit, bidx, bufp, index) \ 226 do {\ 227 if ((mem) == L3_ENTRY_IPV4_MULTICASTm || mem == L3_ENTRY_DOUBLEm) {\ 228 (index) = soc_td2_l3x_bank_entry_hash((unit), (bidx), (bufp));\ 229 } else {\ 230 /* mem is ING_DNAT_ADDRESS_TYPEm */\ 231 (index) = soc_td2_ing_dnat_address_type_bank_entry_hash((unit), (bidx), \ 232 (bufp));\ 233 }\ 234 } while (0) 235 236 #define BCM_TD3_L3UC_DNAT_FIELDS 0 237 #define BCM_TD3_L3UC_SNAT_FIELDS 1 238 #define BCM_TD3_L3MC_FIELDS 2 239 240 #define BCM_TD3_L3UC_SNAT_KEY_TYPE 22 241 #define BCM_TD3_L3UC_DNAT_KEY_TYPE 24 242 #define BCM_TD3_L3MC_NAT_KEY_TYPE 23 243 244 #define BCM_L3_NAT_DATA_TYPE(_u_) \ 245 ((SOC_IS_HELIX5(_u_)) ? (22) : (21)) 246 247 extern int _bcm_esw_l3_nat_init(int unit); 248 extern void _bcm_esw_l3_nat_free_resource(int unit); 249 extern int _bcm_esw_l3_nat_egress_reference_get(int unit, 250 bcm_l3_nat_id_t nat_id, uint32 *ref_count); 251 #if defined (BCM_TRIDENT2_SUPPORT) 252 int _bcm_esw_nat_egress_ref_count_update(int unit, uint32 nat_id, int incr); 253 #endif 254 extern int _bcm_td3_large_nat_egress_add(int unit, bcm_l3_large_nat_egress_t *nat_info); 255 extern int _bcm_td3_large_nat_egress_key_set(int unit, soc_mem_t mem, bcm_l3_large_nat_egress_t *nat_info, int *nat_key, uint32 *entry); 256 extern int _bcm_td3_large_nat_egress_entry_get(int unit, soc_mem_t mem, uint32* entry, uint32 nat_key, bcm_l3_large_nat_egress_t *nat_info); 257 extern int _bcm_td3_large_nat_egress_traverse(int unit, soc_mem_t mem, bcm_l3_large_nat_egress_traverse_cb cb, void *user_data); 258 #endif /* INCLUDE_L3 */ 259 #endif /* _BCM_INT_NAT_H */