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