openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */