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