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

commit cea7802cba88cca67acf3811bd5e1747cb755f6a
parent 4fd10f9bebb821a639f0385a61646588405da8e8
Author: Broadcom SDK Release <sdk.releases@broadcom.com>
Date:   Thu,  6 Aug 2020 12:23:23 -0700

SDK-192126: 1) During propagation callback, bypass MC routes.  2) Fixed also
...

Devices: 56370_A0,56770_A0,56870_A0,56870_B0
Module: ALPM

Symptom:
When there were unicast and multicast routes on the same VRF, applying a
direct route change also applied to multicast, which shouldn't be done

1) During propagation callback, bypass MC routes.  2) Fixed also
vrf_init issue when MC routes are inserted first.

Diffstat:
Msdk-6.5.16/include/bcm_int/esw/alpm.h | 11+++++++++++
Msdk-6.5.16/src/bcm/esw/alpm2/alpm.c | 19++++++++++++++++---
Msdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c | 1+
3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/sdk-6.5.16/include/bcm_int/esw/alpm.h b/sdk-6.5.16/include/bcm_int/esw/alpm.h @@ -315,6 +315,7 @@ typedef struct _alpm_pvt_node_s { uint32 has_def; /* has default route */ uint32 tcam_idx; /* TCAM index in 1st level */ + uint32 pvt_flags; struct _alpm_bkt_node_s *def_pfx; /* Link to bkt_node for bkt def route */ struct _alpm_bkt_info_s bkt_info; /* Bucket info */ @@ -332,6 +333,7 @@ typedef struct _alpm_pvt_ctrl_s { uint32 cnt_add; uint32 cnt_del; + uint8 dr_inited; /* to indicate direct route inited first */ uint8 db_inited; /* database type: FULL | REDUCED * FULL : supports Destination AND @@ -731,6 +733,8 @@ extern alpm_functions_t th_alpm_driver; #define PVT_BKT_IDX(pvt_node) (PVT_BKT_INFO(pvt_node).bkt_idx) #define PVT_SUB_BKT_IDX(pvt_node) (PVT_BKT_INFO(pvt_node).sub_bkt_idx) #define PVT_BKT_VRF(pvt_node) ((pvt_node)->vrf_id) +#define PVT_FLAGS(pvt_node) ((pvt_node)->pvt_flags) +#define PVT_IS_IPMC(pvt_node) (PVT_FLAGS(pvt_node) & BCM_L3_IPMC) #define PVT_BKT_PKM(pvt_node) ((pvt_node)->bkt_pkm) #define PVT_BKT_IPT(pvt_node) (ALPM_PKM2IPT((pvt_node)->bkt_pkm)) #define PVT_BPM_LEN(pvt_node) ((pvt_node)->bpm_len) @@ -849,6 +853,13 @@ extern alpm_functions_t th_alpm_driver; #define ACB_VRF_SPLEN_DIFF2(u, acb, vrf_id, ipt) \ (ACB_PVT_CTRL(acb, vrf_id, ipt).spl_len_diff2) +#define ACB_DR_INITED(u, acb, vrf_id, ipt) \ + ((acb)->pvt_ctl[!!ipt] && \ + ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited) +#define ACB_DR_INIT_SET(u, acb, vrf_id, ipt) \ + (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = TRUE) +#define ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt) \ + (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = FALSE) #define ACB_BNK_CONF(acb) ((acb)->bnk_conf) #define ACB_BNK_BMP(acb, vrf_id, ipt) \ diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c @@ -453,6 +453,11 @@ alpm_ppg_assoc_data_cb(alpm_lib_trie_node_t *trie, alpm_lib_trie_bpm_cb_info_t * pfx_len = ppg_data->key_len; rpl_bpm_len = ppg_data->bpm_len; + /* bypass MC (direct route) for ppg in case of mix UC & MC in same VRF */ + if (PVT_IS_IPMC(pvt_node)) { + return rv; + } + if (user_data->ppg_op == ALPM_PPG_INSERT) { rpl_bpm_len = pfx_len; } @@ -655,6 +660,7 @@ alpm_pvt_trie_insert(int u, _bcm_defip_cfg_t *lpm_cfg) /* Direct route pvt_node doesn't use bkt_trie, def_pfx & bkt_info */ PVT_KEY_LEN(pvt_node) = lpm_cfg->defip_sub_len; PVT_KEY_CPY(pvt_node, lpm_cfg->user_data); + PVT_FLAGS(pvt_node) = lpm_cfg->defip_flags; pvt_trie = ACB_PVT_TRIE(ACB_TOP(u), vrf_id, PVT_BKT_IPT(pvt_node)); rv = alpm_lib_trie_insert(pvt_trie, lpm_cfg->user_data, @@ -679,6 +685,9 @@ alpm_pvt_trie_init(int u, int vrf_id, int ipt) max_key_len = alpm_util_trie_max_key_len(u, ipt); ALPM_IER(alpm_lib_trie_init(max_key_len, &ACB_PVT_TRIE(acb, vrf_id, ipt))); ACB_VRF_INIT_SET(u, acb, vrf_id, ipt); + /* VRF DR partially inited: help to decide alpm_vrf_init + for case of mix MC & UC, in alpm_cb_insert */ + ACB_DR_INIT_SET(u, acb, vrf_id, ipt); return rv; } @@ -2414,6 +2423,7 @@ alpm_bkt_trie_split(int u, _alpm_cb_t *acb, PVT_BKT_PKM(cpn) = pkm; PVT_KEY_CPY(cpn, pvt_key); PVT_KEY_LEN(cpn) = pvt_len; + PVT_FLAGS(cpn) = lpm_cfg->defip_flags; *spl_pvt_node = cpn; *spl_bkt_trie = cbt; @@ -2860,6 +2870,7 @@ alpm_vrf_pvt_node_init(int u, _alpm_cb_t *acb, PVT_BPM_LEN(tmp_node) = 0; PVT_KEY_LEN(tmp_node) = pvt_cfg->defip_sub_len; PVT_KEY_CPY(tmp_node, pvt_cfg->user_data); + PVT_FLAGS(tmp_node) = pvt_cfg->defip_flags; PVT_IDX(tmp_node) = pvt_cfg->defip_index; @@ -3062,6 +3073,7 @@ alpm_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt, uint8 db_type) ALPM_IEG_PRT_EXCEPT(alpm_cb_pvt_add(u, acb, vrf_id, ipt, &pvt_cfg), BCM_E_FULL); ACB_VRF_INIT_SET(u, acb, vrf_id, ipt); + ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt); /* clear DR partially inited */ alpm_vrf_spl_len_calc(u, acb, vrf_id, db_type, &ACB_VRF_SPLEN_DIFF1(u, acb, vrf_id, ipt), @@ -4265,10 +4277,10 @@ alpm_cb_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) _alpm_pvt_node_t *pvt_node, *upr_pvt_node; _alpm_tcam_write_t tcam_write; - /* Init ALPM structure for first insert */ - if (!ACB_VRF_INITED(u, acb, vrf_id, ipt)) { + /* Init ALPM structure for first insert or was DR partially inited (MC first) */ + if (!ACB_VRF_INITED(u, acb, vrf_id, ipt) || ACB_DR_INITED(u, acb, vrf_id, ipt)) { uint8 db_type = alpm_util_route_type_get(u, lpm_cfg); - ALPM_IEG_PRT_EXCEPT(alpm_vrf_init(u, acb, vrf_id, ipt, db_type), BCM_E_FULL); + ALPM_IEG(alpm_vrf_init(u, acb, vrf_id, ipt, db_type)); } if (ACB_BKT_FIXED_FMT(acb, vrf_id)) { @@ -4972,6 +4984,7 @@ bcm_esw_alpm_delete(int u, _bcm_defip_cfg_t *lpm_cfg) if (VRF_ROUTE_CNT(acb, vrf_id, ipt) == 0) { (void)alpm_lib_trie_destroy(ACB_PVT_TRIE(acb, vrf_id, ipt)); ACB_VRF_INIT_CLEAR(u, acb, vrf_id, ipt); + ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt); ACB_PVT_TRIE(acb, vrf_id, ipt) = NULL; } } diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c @@ -142,6 +142,7 @@ alpm_wb_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt) alpm_lib_trie_init(max_key_len, &ACB_PVT_TRIE(acb, vrf_id, ipt))); ACB_VRF_INIT_SET(u, acb, vrf_id, ipt); + ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt); if (ACB_HAS_RTE(acb, vrf_id)) { rv = alpm_lib_trie_init(max_key_len, &ALPM_VRF_TRIE(u, vrf_id, ipt));